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
213 MakeDialog mkDlg(this, TPI_COMMAND_CREATE);
\r
214 if (e.GetClientData() == NULL)
\r
217 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
218 if (fd.ShowModal() == wxID_CANCEL)
\r
222 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
223 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
224 fd.GetFilenames(mkDlg.files);
\r
228 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
229 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
231 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
233 wxFileName fn(mkDlg.files[n]);
\r
234 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
235 mkDlg.files[n] = fn.GetFullPath();
\r
239 this->OnArcClose(e);
\r
240 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
241 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
242 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
243 this->fnArchive.SetEmptyExt();
\r
244 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
247 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
253 int nSelected = mkDlg.chType->GetSelection();
\r
254 swInfo.nArchiveType = mkDlg.afInfo[nSelected].nTypeId;
\r
255 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
256 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
257 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
258 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
259 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
260 swInfo.fCompressHeader = mkDlg.cbCompressHeader->IsChecked();
\r
261 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
262 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
263 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
264 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
265 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
266 mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);
\r
269 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
270 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), TPICallbackProc, mkDlg.afInfo[nSelected].nTypeId))
\r
272 this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));
\r
278 ProcessDialog procDlg(this, mkDlg.files.GetCount());
\r
279 procDlg.Show(true);
\r
281 tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
282 this->ErrorCheck(tpi.nErrorCode);
\r
283 procDlg.Show(false);
\r
287 if (mkDlg.cbOpenAfter->IsChecked())
\r
290 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
293 if (mkDlg.cbExitAfter->IsChecked())
\r
300 this->OnArcOpen(e);
\r
303 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
305 // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。
\r
306 int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;
\r
311 wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
312 if (fd.ShowModal() == wxID_CANCEL)
\r
316 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
317 this->fnArchive = wxFileName(fd.GetPath());
\r
321 ProcessDialog procDlg(this);
\r
322 procDlg.Show(true);
\r
324 // DnD以外で書庫を開く場合、TPIを読み込み。
\r
325 TPI_PROCESSINFO piInfo;
\r
326 piInfo.fiInfo.nUnpackedSize = 0;
\r
327 if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))
\r
329 procDlg.Show(false);
\r
333 this->OnArcCreate(e);
\r
335 else if (this->IsShown())
\r
338 this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);
\r
342 wxLogError(_("No plug-in supporting this archive was found!"));
\r
348 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
349 piInfo.eStatus = 0x1001;
\r
350 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
352 procDlg.Show(false);
\r
353 tpi.CloseArchive();
\r
355 this->OnArcClose(e);
\r
360 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
363 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
364 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
365 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
367 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
368 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
369 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
370 this->tree_ctrl->SetImageList(& g_hIconT);
\r
372 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
374 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(this->fnArchive))),
\r
376 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(this->fnArchive).ConvertToImage().Rescale(16, 16))),
\r
378 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
380 // 巨大書庫のときにファイル名検査を省略するか。
\r
381 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
384 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
386 piInfo.eStatus = 0x1002;
\r
387 piInfo.nProcessedSize = 0;
\r
390 piInfo.nProcessedSize++;
\r
391 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
393 procDlg.Show(false);
\r
394 tpi.CloseArchive();
\r
396 this->OnArcClose(e);
\r
401 if (piInfo.fiInfo.szStoredName.IsEmpty())
\r
403 piInfo.fiInfo.szStoredName = this->fnArchive.GetName();
\r
404 if (piInfo.fiInfo.fnFileName.HasExt())
\r
406 piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();
\r
408 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
413 wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);
\r
414 if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))
\r
416 piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);
\r
419 if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))
\r
425 if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND
\r
426 || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND
\r
427 || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)
\r
429 wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();
\r
430 sz.Replace(wxT("\r"), wxT(" "));
\r
431 sz.Replace(wxT("\n"), wxT(" "));
\r
432 sz.Replace(wxT("\t"), wxT(" "));
\r
433 piInfo.fiInfo.eDanger = TRUE;
\r
434 piInfo.fiInfo.fnFileName = wxFileName(sz);
\r
435 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
441 if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
443 piInfo.fiInfo.eDanger = TRUE;
\r
444 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
446 // 空白の連続による拡張子偽装を検査。
\r
447 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
449 piInfo.fiInfo.eDanger = TRUE;
\r
450 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
453 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
455 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
457 piInfo.fiInfo.eDanger = TRUE;
\r
458 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
462 case 0x200f: c = 0x2027; break;
\r
463 case 0x202e: c = 0x2060; break;
\r
469 bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;
\r
470 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);
\r
472 // ディレクトリ属性を含むものについては情報を保存しない。
\r
479 this->fileinfo.Add(piInfo.fiInfo);
\r
481 while (tpi.GetFileInformation(& piInfo.fiInfo));
\r
484 // GetFileInformationがエラー終了した場合。
\r
485 this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));
\r
488 tpi.GetArchiveInformation(& this->aiArchive);
\r
489 this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));
\r
490 this->szPassword = procDlg.szPassword;
\r
493 tpi.CloseArchive();
\r
494 this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));
\r
497 this->fileinfo.Shrink();
\r
498 this->tree_ctrl->Freeze();
\r
499 if (this->fileinfo.Count() < 10000)
\r
501 this->tree_ctrl->ExpandAll();
\r
502 this->tree_ctrl->SelectItem(idArchive);
\r
506 // ファイル数が多いとソートに時間がかかるので、書庫のルートを表示させる。
\r
507 this->tree_ctrl->Expand(idArcRoot);
\r
508 this->tree_ctrl->SelectItem(idArcRoot);
\r
511 this->tree_ctrl->ScrollTo(idArchive);
\r
512 this->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);
\r
513 this->tree_ctrl->Thaw();
\r
514 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
515 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
518 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
519 this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);
\r
520 this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
521 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
522 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
523 this->statusbar->SetToolTip(
\r
525 _("%s(%s)\nTPI: %s(%s)\nAccess: %s\nModify: %s\nCreate: %s\nComment:\n%s"),
\r
526 this->fnArchive.GetFullName().c_str(), this->aiArchive.fiInfo.szTypeName.c_str(),
\r
527 this->aiArchive.fiInfo.szTPIName.c_str(), this->aiArchive.fiInfo.szEngineName.c_str(),
\r
528 this->aiArchive.tmAccess.Format(_("%Y/%m/%d %H:%M:%S")).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.szComment.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->szPassword.Empty();
\r
574 this->aiArchive.szComment.Empty();
\r
575 this->aiArchive.fnArchive.Clear();
\r
576 this->aiArchive.fiInfo.szTypeName.Empty();
\r
577 this->aiArchive.fiInfo.szSuffix.Empty();
\r
578 this->aiArchive.fiInfo.szEngineName.Empty();
\r
579 this->aiArchive.fiInfo.szTPIName.Empty();
\r
581 g_hIconT.RemoveAll();
\r
582 g_hIconLL.RemoveAll();
\r
583 g_hIconLS.RemoveAll();
\r
585 // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。
\r
586 if (e.GetExtraLong() == 0)
\r
592 void MainFrame::OnArcClone(wxCommandEvent&)
\r
595 wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
596 if (fd.ShowModal() == wxID_CANCEL)
\r
600 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
603 ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());
\r
604 wxFileName fn(fd.GetPath());
\r
605 wxDateTime dtAccess, dtModify, dtCreate;
\r
606 this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);
\r
607 fn.SetTimes(& dtAccess, & dtModify, & dtCreate);
\r
610 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
613 MakeDialog mkDlg(this, TPI_COMMAND_ADD);
\r
615 TPI_SWITCHES swInfo;
\r
616 swInfo.pCustomSwitches = NULL;
\r
618 if (e.GetClientData() == NULL)
\r
620 if (::wxGetKeyState(WXK_SHIFT))
\r
623 wxDirDialog dd(this, _("Choose dir to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);
\r
624 if (dd.ShowModal() == wxID_CANCEL)
\r
628 swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());
\r
629 this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());
\r
630 mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());
\r
635 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
636 if (fd.ShowModal() == wxID_CANCEL)
\r
640 fd.GetFilenames(mkDlg.files);
\r
641 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
642 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
647 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
648 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
650 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
652 wxFileName fn(mkDlg.files[n]);
\r
653 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
654 mkDlg.files[n] = fn.GetFullPath();
\r
659 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
665 swInfo.fMakeSFX = false;
\r
666 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
667 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
668 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
669 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
670 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
671 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
672 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
673 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
674 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
678 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
679 procDlg.Show(true);
\r
681 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
682 this->ErrorCheck(tpi.nErrorCode);
\r
683 procDlg.Show(false);
\r
686 if (mkDlg.cbOpenAfter->IsChecked())
\r
689 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
692 if (mkDlg.cbExitAfter->IsChecked())
\r
698 // 終了しない場合は書庫を再読み込み。
\r
699 this->OnArcOpen(e);
\r
702 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
704 TPI_SWITCHES swInfo;
\r
705 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
708 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
709 if (fd.ShowModal() == wxID_CANCEL)
\r
713 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
714 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
716 wxArrayString files;
\r
717 files.Add(fd.GetPath());
\r
719 ProcessDialog procDlg(this);
\r
720 procDlg.Show(true);
\r
721 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
722 this->ErrorCheck(tpi.nErrorCode);
\r
723 procDlg.Show(false);
\r
726 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
728 TPI_SWITCHES swInfo;
\r
729 swInfo.pCustomSwitches = NULL;
\r
730 swInfo.szPassword = this->szPassword;
\r
732 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
733 int nMode = e.GetInt();
\r
734 if (e.GetInt() == 8)
\r
739 wxFileType * ftFile = NULL;
\r
741 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
742 MakeDialog mkDlg(this, TPI_COMMAND_EXTRACT);
\r
743 mkDlg.files = MakeTargetFileList(this, nMode == 1, nMode == 0);
\r
745 bool bMakeDir = false;
\r
749 swInfo.fStoreDirectoryPathes = false;
\r
750 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
751 if (szDestDirBase == wxT("-----"))
\r
753 // 書庫ルートのときは書庫名にしておく。
\r
754 szDestDirBase = this->fnArchive.GetName();
\r
756 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(wxStandardPaths::Get().GetTempDir()), szDestDirBase, true);
\r
757 if (! swInfo.fnDestinationDirectory.IsOk())
\r
759 wxLogError(_("Unable to make the temporary directory!"));
\r
765 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
771 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
772 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
773 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
774 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
776 // 必要なら書庫名でディレクトリを作成する。
\r
777 bMakeDir = WillMakeDirByArcName(this, & mkDlg);
\r
780 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
781 if (! swInfo.fnDestinationDirectory.IsOk())
\r
783 wxLogError(_("Unable to make the destination directory!"));
\r
791 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
792 procDlg.Show(true);
\r
794 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
795 this->ErrorCheck(tpi.nErrorCode);
\r
796 procDlg.Show(false);
\r
801 if (mkDlg.cbOpenAfter->IsChecked())
\r
804 if (mkDlg.chDirMake->GetSelection() == 2 && ! bMakeDir)
\r
806 wxTreeItemId tiArcSub = this->tree_ctrl->GetLastChild(this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()));
\r
807 if (tiArcSub.IsOk())
\r
809 swInfo.fnDestinationDirectory.SetFullName(this->tree_ctrl->GetItemText(tiArcSub));
\r
812 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
815 if (mkDlg.cbExitAfter->IsChecked())
\r
826 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
827 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
829 // 種類が取得できないときはテキストとみなす。
\r
830 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
834 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
835 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
836 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
840 // Linuxでは引用符で囲む必要がある。
\r
841 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
843 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
848 pCallback->OnTerminate(0, 0);
\r
854 wxArrayString asFiles;
\r
855 myFileDataObject * objFile = new myFileDataObject();
\r
856 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
857 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
859 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
862 asFiles.Add(szFileName);
\r
867 objFile->AddFile(szFileName);
\r
872 objFile->AddFile(objFile->szTempDir);
\r
877 wxTheClipboard->SetData(objFile);
\r
881 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
882 this->SetDropTarget(NULL);
\r
885 wxDropSource dropSource(* objFile, this);
\r
886 wxDragResult drResult = dropSource.DoDragDrop();
\r
887 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
890 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
894 this->SetDropTarget(new myFileDropTarget(this));
\r
896 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
899 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
901 chmod(asFiles[i].ToUTF8(), 0600);
\r
902 ::wxRemoveFile(asFiles[i]);
\r
912 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
914 // 全ファイル削除は危険ではないかと。
\r
915 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
917 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
918 SetMenuToolState("Arc_Delete", false);
\r
922 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
929 wxArrayString asFiles = MakeTargetFileList(this);
\r
930 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
931 procDlg.Show(true);
\r
933 TPI_SWITCHES swInfo;
\r
934 swInfo.szPassword = this->szPassword;
\r
935 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
936 this->ErrorCheck(tpi.nErrorCode);
\r
937 procDlg.Show(false);
\r
941 this->OnArcOpen(e);
\r
944 void MainFrame::OnArcTest(wxCommandEvent&)
\r
947 wxArrayString asFiles = MakeTargetFileList(this);
\r
948 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
949 procDlg.Show(true);
\r
951 TPI_SWITCHES swInfo;
\r
952 swInfo.szPassword = this->szPassword;
\r
953 tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
954 this->ErrorCheck(tpi.nErrorCode);
\r
955 procDlg.Show(false);
\r
958 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
961 wxArrayString asFiles = MakeTargetFileList(this);
\r
962 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
963 procDlg.Show(true);
\r
965 TPI_SWITCHES swInfo;
\r
966 swInfo.szPassword = this->szPassword;
\r
967 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
968 this->ErrorCheck(tpi.nErrorCode);
\r
969 procDlg.Show(false);
\r
972 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
974 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
976 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
977 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
981 if (! wxTheClipboard->Open())
\r
987 this->OnArcExtract(e);
\r
988 wxTheClipboard->Close();
\r
991 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
994 this->menubar->Check(n, true);
\r
995 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
996 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
997 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
1000 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
1002 this->toolbar->Show(e.IsChecked());
\r
1005 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
1007 this->statusbar->Show(e.IsChecked());
\r
1010 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
1012 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
1014 this->list_ctrl->Select(i, true);
\r
1020 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1023 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1025 this->list_ctrl->apShowFile.Clear();
\r
1026 this->list_ctrl->DeleteAllItems();
\r
1027 g_hIconLL.RemoveAll();
\r
1028 g_hIconLS.RemoveAll();
\r
1030 // 現在のアイテムの選択状態を無効にしておく。
\r
1031 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1032 while (nSelected != -1)
\r
1034 this->list_ctrl->Select(nSelected, false);
\r
1035 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1039 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1040 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1042 // 配列と比較し、パスが一致しなければ消す。
\r
1043 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1046 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1048 // 項目がフォルダであるなら無視。
\r
1049 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
1054 // フィルタにかからなければ無視。
\r
1055 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1060 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1065 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1066 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1069 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1071 // TODO : アイテムが子階層を持っていても展開できない。
\r
1072 this->tree_ctrl->SelectItem(e.GetItem());
\r
1074 wxCommandEvent e1;
\r
1076 this->OnArcExtract(e1);
\r
1079 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1081 wxPoint p = e.GetPosition();
\r
1082 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1087 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1089 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1090 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1091 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1092 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1095 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1099 this->OnArcExtract(e);
\r
1102 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1104 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1106 // アイテムを選択せずドラッグしようとした場合。
\r
1112 this->OnArcExtract(e);
\r
1117 void MainFrame::OnFilter(wxCommandEvent&)
\r
1120 e.SetItem(this->tree_ctrl->GetSelection());
\r
1121 this->OnTreeChanged(e);
\r
1126 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1128 // 書庫を開いていれば閉じておく。
\r
1130 this->OnArcClose(e);
\r
1133 wxDir fs(L_DIR_B_LIB);
\r
1134 wxString szTPIName;
\r
1135 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1140 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc))
\r
1142 tpi.FreeLibrary();
\r
1147 if (! tpi.OpenArchive(szFileName, llFileCount))
\r
1149 tpi.FreeLibrary();
\r
1150 * llFileCount = 0;
\r
1155 while (fs.GetNext(& szTPIName));
\r
1160 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1162 switch (nErrorCode)
\r
1164 case TPI_ERROR_SUCCESS:
\r
1165 case TPI_ERROR_S_ENDOFDATA:
\r
1166 case TPI_CALLBACK_CONTINUE:
\r
1168 case TPI_ERROR_D_UNSUPPORTED:
\r
1169 wxLogError(_("Sorry, this function is not supported yet."));
\r
1171 case TPI_ERROR_D_SKIPPED:
\r
1172 case TPI_CALLBACK_CANCEL:
\r
1175 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1177 return nErrorCode;
\r