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)\nModify: %s\nCreate: %s\nTPI: %s(%s)"),
\r
528 this->fnArchive.GetFullName().c_str(), this->aiArchive.fiInfo.szTypeName.c_str(),
\r
529 this->aiArchive.tmModify.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
530 this->aiArchive.tmCreate.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
531 this->aiArchive.fiInfo.szTPIName.c_str(), this->aiArchive.fiInfo.szEngineName.c_str()
\r
535 // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。
\r
536 SetMenuToolState("Arc_Close", true);
\r
537 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
538 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
539 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
540 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
541 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
542 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
543 this->menubar->Enable(XRCID("Arc_Clone"), true);
\r
545 procDlg.Show(false);
\r
549 void MainFrame::OnArcClose(wxCommandEvent& e)
\r
551 // ツリービュー・リストビュー設定。
\r
552 this->tree_ctrl->DeleteAllItems();
\r
553 this->list_ctrl->DeleteAllItems();
\r
554 this->list_ctrl->apShowFile.Clear();
\r
557 SetMenuToolState("Arc_Close", false);
\r
558 SetMenuToolState("Arc_Add", false);
\r
559 SetMenuToolState("Arc_SFX", false);
\r
560 SetMenuToolState("Arc_UnSFX", false);
\r
561 SetMenuToolState("Arc_Extract", false);
\r
562 SetMenuToolState("Arc_Delete", false);
\r
563 SetMenuToolState("Arc_Test", false);
\r
564 SetMenuToolState("Arc_Repair", false);
\r
565 this->menubar->Enable(XRCID("Arc_Clone"), false);
\r
567 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
569 this->statusbar->SetStatusText(wxEmptyString, i);
\r
571 this->statusbar->SetToolTip(wxEmptyString);
\r
572 this->fileinfo.Clear();
\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
613 mkDlg.SetParent(this);
\r
614 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
616 TPI_SWITCHES swInfo;
\r
617 swInfo.pCustomSwitches = NULL;
\r
619 if (e.GetClientData() == NULL)
\r
621 if (::wxGetKeyState(WXK_SHIFT))
\r
624 wxDirDialog dd(this, _("Choose dir to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);
\r
625 if (dd.ShowModal() == wxID_CANCEL)
\r
629 swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());
\r
630 this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());
\r
631 mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());
\r
636 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
637 if (fd.ShowModal() == wxID_CANCEL)
\r
641 fd.GetFilenames(mkDlg.files);
\r
642 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
643 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
648 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
649 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
651 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
653 wxFileName fn(mkDlg.files[n]);
\r
654 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
655 mkDlg.files[n] = fn.GetFullPath();
\r
660 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
666 swInfo.fMakeSFX = false;
\r
667 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
668 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
669 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
670 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
671 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
672 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
673 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
674 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
675 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
679 ProcessDialog procDlg;
\r
680 procDlg.fnArchive = & this->fnArchive;
\r
681 procDlg.nFileCount = mkDlg.files.GetCount();
\r
682 procDlg.Show(true);
\r
684 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
685 this->ErrorCheck(tpi.nErrorCode);
\r
686 procDlg.Show(false);
\r
689 if (mkDlg.cbOpenAfter->IsChecked())
\r
692 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
695 if (mkDlg.cbExitAfter->IsChecked())
\r
701 // 終了しない場合は書庫を再読み込み。
\r
702 this->OnArcOpen(e);
\r
705 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
707 TPI_SWITCHES swInfo;
\r
708 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
711 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
712 if (fd.ShowModal() == wxID_CANCEL)
\r
716 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
717 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
719 wxArrayString files;
\r
720 files.Add(fd.GetPath());
\r
722 ProcessDialog procDlg;
\r
723 procDlg.Show(true);
\r
724 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
725 this->ErrorCheck(tpi.nErrorCode);
\r
726 procDlg.Show(false);
\r
729 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
731 TPI_SWITCHES swInfo;
\r
732 swInfo.pCustomSwitches = NULL;
\r
734 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
735 int nMode = e.GetInt();
\r
736 if (e.GetInt() == 8)
\r
741 wxFileType * ftFile = NULL;
\r
743 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
745 mkDlg.SetParent(this);
\r
746 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
747 mkDlg.files = MakeTargetFileList(this, nMode == 1, nMode == 0);
\r
749 bool bMakeDir = false;
\r
753 swInfo.fStoreDirectoryPathes = false;
\r
754 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
756 if (szDestDirBase == wxT("-----"))
\r
758 // 書庫ルートのときは書庫名にしておく。
\r
759 szDestDirBase = this->fnArchive.GetName();
\r
761 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(p.GetTempDir()), szDestDirBase, true);
\r
762 if (! swInfo.fnDestinationDirectory.IsOk())
\r
764 wxLogError(_("Unable to make the temporary directory!"));
\r
770 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
776 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
777 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
778 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
779 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
781 // 必要なら書庫名でディレクトリを作成する。
\r
782 bMakeDir = WillMakeDirByArcName(this, & mkDlg);
\r
785 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
786 if (! swInfo.fnDestinationDirectory.IsOk())
\r
788 wxLogError(_("Unable to make the destination directory!"));
\r
796 ProcessDialog procDlg;
\r
797 procDlg.fnArchive = & this->fnArchive;
\r
798 procDlg.nFileCount = mkDlg.files.GetCount();
\r
799 procDlg.Show(true);
\r
801 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
802 this->ErrorCheck(tpi.nErrorCode);
\r
803 procDlg.Show(false);
\r
808 if (mkDlg.cbOpenAfter->IsChecked())
\r
811 if (mkDlg.chDirMake->GetSelection() == 2 && ! bMakeDir)
\r
813 wxTreeItemId tiArcSub = this->tree_ctrl->GetLastChild(this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()));
\r
814 if (tiArcSub.IsOk())
\r
816 swInfo.fnDestinationDirectory.SetFullName(this->tree_ctrl->GetItemText(tiArcSub));
\r
819 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
822 if (mkDlg.cbExitAfter->IsChecked())
\r
833 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
834 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
836 // 種類が取得できないときはテキストとみなす。
\r
837 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
841 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
842 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
843 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
847 // Linuxでは引用符で囲む必要がある。
\r
848 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
850 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
855 pCallback->OnTerminate(0, 0);
\r
861 wxArrayString asFiles;
\r
862 myFileDataObject * objFile = new myFileDataObject();
\r
863 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
864 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
866 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
869 asFiles.Add(szFileName);
\r
874 objFile->AddFile(szFileName);
\r
879 objFile->AddFile(objFile->szTempDir);
\r
884 wxTheClipboard->SetData(objFile);
\r
888 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
889 this->SetDropTarget(NULL);
\r
892 wxDropSource dropSource(* objFile, this);
\r
893 wxDragResult drResult = dropSource.DoDragDrop();
\r
894 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
897 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
901 this->SetDropTarget(new myFileDropTarget(this));
\r
903 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
906 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
908 chmod(asFiles[i].ToUTF8(), 0600);
\r
909 ::wxRemoveFile(asFiles[i]);
\r
919 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
921 // 全ファイル削除は危険ではないかと。
\r
922 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
924 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
925 SetMenuToolState("Arc_Delete", false);
\r
929 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
936 wxArrayString asFiles = MakeTargetFileList(this);
\r
937 ProcessDialog procDlg;
\r
938 procDlg.fnArchive = & this->fnArchive;
\r
939 procDlg.nFileCount = asFiles.GetCount();
\r
940 procDlg.Show(true);
\r
942 TPI_SWITCHES swInfo;
\r
943 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
944 this->ErrorCheck(tpi.nErrorCode);
\r
945 procDlg.Show(false);
\r
949 this->OnArcOpen(e);
\r
952 void MainFrame::OnArcTest(wxCommandEvent&)
\r
955 wxArrayString asFiles = MakeTargetFileList(this);
\r
956 ProcessDialog procDlg;
\r
957 procDlg.fnArchive = & this->fnArchive;
\r
958 procDlg.nFileCount = asFiles.GetCount();
\r
959 procDlg.Show(true);
\r
961 TPI_SWITCHES swInfo;
\r
962 bool bIsCorrect = tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
963 procDlg.Show(false);
\r
967 wxLogMessage(_("This is a correct archive."));
\r
971 this->ErrorCheck(tpi.nErrorCode);
\r
975 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
978 wxArrayString asFiles = MakeTargetFileList(this);
\r
979 ProcessDialog procDlg;
\r
980 procDlg.fnArchive = & this->fnArchive;
\r
981 procDlg.nFileCount = asFiles.GetCount();
\r
982 procDlg.Show(true);
\r
984 TPI_SWITCHES swInfo;
\r
985 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
986 this->ErrorCheck(tpi.nErrorCode);
\r
987 procDlg.Show(false);
\r
990 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
992 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
994 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
995 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
999 if (! wxTheClipboard->Open())
\r
1005 this->OnArcExtract(e);
\r
1006 wxTheClipboard->Close();
\r
1009 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
1011 int n = e.GetId();
\r
1012 this->menubar->Check(n, true);
\r
1013 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
1014 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
1015 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
1018 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
1020 this->toolbar->Show(e.IsChecked());
\r
1023 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
1025 this->statusbar->Show(e.IsChecked());
\r
1028 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
1030 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
1032 this->list_ctrl->Select(i, true);
\r
1038 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1041 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1043 this->list_ctrl->apShowFile.Clear();
\r
1044 this->list_ctrl->DeleteAllItems();
\r
1045 g_hIconLL.RemoveAll();
\r
1046 g_hIconLS.RemoveAll();
\r
1048 // 現在のアイテムの選択状態を無効にしておく。
\r
1049 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1050 while (nSelected != -1)
\r
1052 this->list_ctrl->Select(nSelected, false);
\r
1053 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1057 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1058 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1060 // 配列と比較し、パスが一致しなければ消す。
\r
1061 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1064 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1066 // 項目がフォルダであるなら無視。
\r
1067 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
1072 // フィルタにかからなければ無視。
\r
1073 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1078 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1083 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1084 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1087 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1089 // TODO : アイテムが子階層を持っていても展開できない。
\r
1090 this->tree_ctrl->SelectItem(e.GetItem());
\r
1092 wxCommandEvent e1;
\r
1094 this->OnArcExtract(e1);
\r
1097 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1099 wxPoint p = e.GetPosition();
\r
1100 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1105 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1107 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1108 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1109 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1110 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1113 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1117 this->OnArcExtract(e);
\r
1120 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1122 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1124 // アイテムを選択せずドラッグしようとした場合。
\r
1130 this->OnArcExtract(e);
\r
1135 void MainFrame::OnFilter(wxCommandEvent&)
\r
1138 e.SetItem(this->tree_ctrl->GetSelection());
\r
1139 this->OnTreeChanged(e);
\r
1144 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1146 // 書庫を開いていれば閉じておく。
\r
1148 this->OnArcClose(e);
\r
1151 wxDir fs(L_DIR_B_LIB);
\r
1152 wxString szTPIName;
\r
1153 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1158 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc))
\r
1160 tpi.FreeLibrary();
\r
1165 if (! tpi.OpenArchive(szFileName, llFileCount))
\r
1167 tpi.FreeLibrary();
\r
1168 * llFileCount = 0;
\r
1173 while (fs.GetNext(& szTPIName));
\r
1178 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1180 switch (nErrorCode)
\r
1182 case TPI_ERROR_SUCCESS:
\r
1183 case TPI_ERROR_S_ENDOFDATA:
\r
1184 case TPI_CALLBACK_CONTINUE:
\r
1186 case TPI_ERROR_D_UNSUPPORTED:
\r
1187 wxLogError(_("Sorry, this function is not supported yet."));
\r
1189 case TPI_ERROR_D_SKIPPED:
\r
1190 case TPI_CALLBACK_CANCEL:
\r
1191 wxLogError(_("This operation is canceled by the user."));
\r
1194 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1196 return nErrorCode;
\r