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 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
215 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
217 if (e.GetClientData() == NULL)
\r
220 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
221 if (fd.ShowModal() == wxID_CANCEL)
\r
225 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
226 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
227 fd.GetFilenames(mkDlg.files);
\r
231 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
232 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
234 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
236 wxFileName fn(mkDlg.files[n]);
\r
237 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
238 mkDlg.files[n] = fn.GetFullPath();
\r
242 this->OnArcClose(e);
\r
243 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
244 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
245 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
246 this->fnArchive.SetEmptyExt();
\r
247 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
250 if (mkDlg.ShowModal() == wxID_CANCEL)
\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 int nSelected = mkDlg.chType->GetSelection();
\r
271 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
272 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].nTypeId))
\r
274 this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));
\r
279 tpi.SetCallbackProc(TPICallbackProc);
\r
280 this->ErrorCheck(tpi.nErrorCode, wxT("SetCallbackProc"));
\r
284 ProcessDialog procDlg;
\r
285 procDlg.Show(true);
\r
288 TPI_PROCESSINFO piInfo;
\r
289 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
290 piInfo.eStatus = 0x1000;
\r
291 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
292 piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();
\r
293 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
295 tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
296 this->ErrorCheck(tpi.nErrorCode);
\r
297 procDlg.Show(false);
\r
301 if (mkDlg.cbOpenAfter->IsChecked())
\r
304 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
307 if (mkDlg.cbExitAfter->IsChecked())
\r
314 this->OnArcOpen(e);
\r
317 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
319 // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。
\r
320 int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;
\r
325 wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
326 if (fd.ShowModal() == wxID_CANCEL)
\r
330 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
331 this->fnArchive = wxFileName(fd.GetPath());
\r
335 ProcessDialog procDlg;
\r
336 procDlg.Show(true);
\r
338 // DnD以外で書庫を開く場合、TPIを読み込み。
\r
339 TPI_PROCESSINFO piInfo;
\r
340 piInfo.fiInfo.nUnpackedSize = e.GetExtraLong();
\r
341 if (nMode != 2 && ! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))
\r
343 procDlg.Show(false);
\r
345 if (this->IsShown())
\r
348 this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);
\r
352 wxLogError(_("No plug-in supporting this archive was found!"));
\r
359 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
360 piInfo.eStatus = 0x1000;
\r
361 piInfo.nProcessedSize = 0;
\r
362 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
363 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
366 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
369 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
370 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
371 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
373 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
374 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
375 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
376 this->tree_ctrl->SetImageList(& g_hIconT);
\r
378 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
380 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
382 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
384 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
387 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
389 piInfo.eStatus = 0x1001;
\r
392 piInfo.nProcessedSize++;
\r
393 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
395 procDlg.Show(false);
\r
396 tpi.CloseArchive();
\r
398 this->OnArcClose(e);
\r
403 if (piInfo.fiInfo.szStoredName.IsEmpty())
\r
405 piInfo.fiInfo.szStoredName = this->fnArchive.GetName();
\r
406 if (piInfo.fiInfo.fnFileName.HasExt())
\r
408 piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();
\r
410 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
415 wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);
\r
416 if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))
\r
418 piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);
\r
421 if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))
\r
427 if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND
\r
428 || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND
\r
429 || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)
\r
431 wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();
\r
432 sz.Replace(wxT("\r"), wxT(" "));
\r
433 sz.Replace(wxT("\n"), wxT(" "));
\r
434 sz.Replace(wxT("\t"), wxT(" "));
\r
435 piInfo.fiInfo.eDanger = TRUE;
\r
436 piInfo.fiInfo.fnFileName = wxFileName(sz);
\r
437 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
468 bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;
\r
469 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);
\r
471 // ディレクトリ属性を含むものについては情報を保存しない。
\r
478 this->fileinfo.Add(piInfo.fiInfo);
\r
480 while (tpi.GetFileInformation(& piInfo.fiInfo));
\r
483 // GetFileInformationがエラー終了した場合。
\r
484 this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));
\r
487 tpi.GetArchiveInformation(& this->aiArchive);
\r
488 this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));
\r
491 tpi.CloseArchive();
\r
492 this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));
\r
495 this->fileinfo.Shrink();
\r
496 this->tree_ctrl->ExpandAll();
\r
497 this->tree_ctrl->ScrollTo(idArchive);
\r
498 this->tree_ctrl->SelectItem(idArchive);
\r
499 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
500 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
503 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
504 this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);
\r
505 this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
506 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
507 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
509 // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。
\r
510 SetMenuToolState("Arc_Close", true);
\r
511 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
512 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
513 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
514 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
515 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
516 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
517 this->menubar->Enable(XRCID("Arc_Clone"), true);
\r
519 procDlg.Show(false);
\r
523 void MainFrame::OnArcClose(wxCommandEvent& e)
\r
525 // ツリービュー・リストビュー設定。
\r
526 this->tree_ctrl->DeleteAllItems();
\r
527 this->list_ctrl->DeleteAllItems();
\r
528 this->list_ctrl->apShowFile.Clear();
\r
531 SetMenuToolState("Arc_Close", false);
\r
532 SetMenuToolState("Arc_Add", false);
\r
533 SetMenuToolState("Arc_SFX", false);
\r
534 SetMenuToolState("Arc_UnSFX", false);
\r
535 SetMenuToolState("Arc_Extract", false);
\r
536 SetMenuToolState("Arc_Delete", false);
\r
537 SetMenuToolState("Arc_Test", false);
\r
538 SetMenuToolState("Arc_Repair", false);
\r
539 this->menubar->Enable(XRCID("Arc_Clone"), false);
\r
541 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
543 this->statusbar->SetStatusText(wxEmptyString, i);
\r
545 this->fileinfo.Clear();
\r
546 this->aiArchive.szComment.Empty();
\r
547 this->aiArchive.fnArchive.Clear();
\r
548 this->aiArchive.fiInfo.szTypeName.Empty();
\r
549 this->aiArchive.fiInfo.szSuffix.Empty();
\r
550 this->aiArchive.fiInfo.szEngineName.Empty();
\r
551 this->aiArchive.fiInfo.szTPIName.Empty();
\r
553 g_hIconT.RemoveAll();
\r
554 g_hIconLL.RemoveAll();
\r
555 g_hIconLS.RemoveAll();
\r
557 // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。
\r
558 if (e.GetExtraLong() == 0)
\r
564 void MainFrame::OnArcClone(wxCommandEvent&)
\r
567 wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
568 if (fd.ShowModal() == wxID_CANCEL)
\r
572 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
575 ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());
\r
576 wxFileName fn(fd.GetPath());
\r
577 wxDateTime dtAccess, dtModify, dtCreate;
\r
578 this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);
\r
579 fn.SetTimes(& dtAccess, & dtModify, & dtCreate);
\r
582 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
586 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
587 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
588 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
591 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
592 if (fd.ShowModal() == wxID_CANCEL)
\r
596 fd.GetFilenames(mkDlg.files);
\r
597 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
600 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
606 TPI_SWITCHES swInfo;
\r
607 swInfo.pCustomSwitches = NULL;
\r
608 swInfo.fMakeSFX = false;
\r
609 swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());
\r
610 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
611 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
612 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
613 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
614 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
615 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
616 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
617 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
618 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
622 ProcessDialog procDlg;
\r
623 procDlg.Show(true);
\r
626 TPI_PROCESSINFO piInfo;
\r
627 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
628 piInfo.eStatus = 0x1000;
\r
629 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
630 piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();
\r
631 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
633 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
634 this->ErrorCheck(tpi.nErrorCode);
\r
635 procDlg.Show(false);
\r
638 if (mkDlg.cbOpenAfter->IsChecked())
\r
641 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
644 if (mkDlg.cbExitAfter->IsChecked())
\r
650 // 終了しない場合は書庫を再読み込み。
\r
651 this->OnArcOpen(e);
\r
654 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
656 TPI_SWITCHES swInfo;
\r
657 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
660 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
661 if (fd.ShowModal() == wxID_CANCEL)
\r
665 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
666 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
668 wxArrayString files;
\r
669 files.Add(fd.GetPath());
\r
671 ProcessDialog procDlg;
\r
672 procDlg.Show(true);
\r
673 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
674 this->ErrorCheck(tpi.nErrorCode);
\r
675 procDlg.Show(false);
\r
678 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
680 TPI_SWITCHES swInfo;
\r
681 swInfo.pCustomSwitches = NULL;
\r
683 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
684 int nMode = e.GetInt();
\r
685 if (e.GetInt() == 8)
\r
690 wxFileType * ftFile = NULL;
\r
692 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
694 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
695 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
696 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
697 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
702 swInfo.fStoreDirectoryPathes = false;
\r
703 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
705 if (szDestDirBase == wxT("-----"))
\r
707 // 書庫ルートのときは書庫名にしておく。
\r
708 szDestDirBase = this->fnArchive.GetName();
\r
710 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(p.GetTempDir()), szDestDirBase, true);
\r
711 if (! swInfo.fnDestinationDirectory.IsOk())
\r
713 wxLogError(_("Unable to make the temporary directory!"));
\r
719 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
725 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
726 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
727 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
728 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
730 // 必要なら書庫名でディレクトリを作成する。
\r
731 if (WillMakeDirByArcName(this, & mkDlg))
\r
733 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
734 if (! swInfo.fnDestinationDirectory.IsOk())
\r
736 wxLogError(_("Unable to make the destination directory!"));
\r
744 ProcessDialog procDlg;
\r
745 procDlg.Show(true);
\r
748 TPI_PROCESSINFO piInfo;
\r
749 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
750 piInfo.eStatus = 0x1000;
\r
751 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
752 piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();
\r
753 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
755 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
756 this->ErrorCheck(tpi.nErrorCode);
\r
757 procDlg.Show(false);
\r
762 if (mkDlg.cbOpenAfter->IsChecked())
\r
765 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
768 if (mkDlg.cbExitAfter->IsChecked())
\r
779 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
780 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
782 // 種類が取得できないときはテキストとみなす。
\r
783 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
787 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
788 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
789 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
793 // Linuxでは引用符で囲む必要がある。
\r
794 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
796 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
801 pCallback->OnTerminate(0, 0);
\r
807 wxArrayString asFiles;
\r
808 myFileDataObject * objFile = new myFileDataObject();
\r
809 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
810 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
812 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
815 asFiles.Add(szFileName);
\r
820 objFile->AddFile(szFileName);
\r
825 objFile->AddFile(objFile->szTempDir);
\r
830 wxTheClipboard->SetData(objFile);
\r
834 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
835 this->SetDropTarget(NULL);
\r
838 wxDropSource dropSource(* objFile, this);
\r
839 wxDragResult drResult = dropSource.DoDragDrop();
\r
840 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
843 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
847 this->SetDropTarget(new myFileDropTarget(this));
\r
849 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
852 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
854 chmod(asFiles[i].ToUTF8(), 0600);
\r
855 ::wxRemoveFile(asFiles[i]);
\r
865 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
867 // 全ファイル削除は危険ではないかと。
\r
868 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
870 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
871 SetMenuToolState("Arc_Delete", false);
\r
875 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
882 TPI_SWITCHES swInfo;
\r
883 ProcessDialog procDlg;
\r
884 procDlg.Show(true);
\r
885 wxArrayString asFiles = MakeTargetFileList(this, false);
\r
888 TPI_PROCESSINFO piInfo;
\r
889 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
890 piInfo.eStatus = 0x1000;
\r
891 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
892 piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();
\r
893 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
895 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
896 this->ErrorCheck(tpi.nErrorCode);
\r
897 procDlg.Show(false);
\r
901 this->OnArcOpen(e);
\r
904 void MainFrame::OnArcTest(wxCommandEvent&)
\r
907 ProcessDialog procDlg;
\r
908 procDlg.Show(true);
\r
909 wxArrayString asFiles = MakeTargetFileList(this, false);
\r
912 TPI_PROCESSINFO piInfo;
\r
913 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
914 piInfo.eStatus = 0x1000;
\r
915 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
916 piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();
\r
917 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
919 TPI_SWITCHES swInfo;
\r
920 bool bIsCorrect = tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
921 procDlg.Show(false);
\r
925 wxLogMessage(_("This is a correct archive."));
\r
929 this->ErrorCheck(tpi.nErrorCode);
\r
933 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
936 ProcessDialog procDlg;
\r
937 procDlg.Show(true);
\r
938 wxArrayString asFiles = MakeTargetFileList(this, false);
\r
941 TPI_PROCESSINFO piInfo;
\r
942 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
943 piInfo.eStatus = 0x1000;
\r
944 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
945 piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();
\r
946 procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
948 TPI_SWITCHES swInfo;
\r
949 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
950 this->ErrorCheck(tpi.nErrorCode);
\r
951 procDlg.Show(false);
\r
954 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
956 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
958 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
959 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
963 if (! wxTheClipboard->Open())
\r
969 this->OnArcExtract(e);
\r
970 wxTheClipboard->Close();
\r
973 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
976 this->menubar->Check(n, true);
\r
977 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
978 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
979 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
982 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
984 this->toolbar->Show(e.IsChecked());
\r
987 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
989 this->statusbar->Show(e.IsChecked());
\r
992 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
994 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
996 this->list_ctrl->Select(i, true);
\r
1002 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1005 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1007 this->list_ctrl->apShowFile.Clear();
\r
1008 this->list_ctrl->DeleteAllItems();
\r
1009 g_hIconLL.RemoveAll();
\r
1010 g_hIconLS.RemoveAll();
\r
1012 // 現在のアイテムの選択状態を無効にしておく。
\r
1013 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1014 while (nSelected != -1)
\r
1016 this->list_ctrl->Select(nSelected, false);
\r
1017 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1021 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1022 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1024 // 配列と比較し、パスが一致しなければ消す。
\r
1025 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1028 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1030 // 項目がフォルダであるなら無視。
\r
1031 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
1036 // フィルタにかからなければ無視。
\r
1037 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1042 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1047 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1048 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1051 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1053 // TODO : アイテムが子階層を持っていても展開できない。
\r
1054 this->tree_ctrl->SelectItem(e.GetItem());
\r
1056 wxCommandEvent e1;
\r
1058 this->OnArcExtract(e1);
\r
1061 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1063 wxPoint p = e.GetPosition();
\r
1064 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1069 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1071 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1072 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1073 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1074 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1077 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1081 this->OnArcExtract(e);
\r
1084 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1086 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1088 // アイテムを選択せずドラッグしようとした場合。
\r
1094 this->OnArcExtract(e);
\r
1099 void MainFrame::OnFilter(wxCommandEvent&)
\r
1102 e.SetItem(this->tree_ctrl->GetSelection());
\r
1103 this->OnTreeChanged(e);
\r
1108 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1110 // 書庫を開いていれば閉じておく。
\r
1112 this->OnArcClose(e);
\r
1115 wxDir fs(L_DIR_B_LIB);
\r
1116 wxString szTPIName;
\r
1117 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1122 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName))
\r
1124 tpi.FreeLibrary();
\r
1129 tpi.SetCallbackProc(TPICallbackProc);
\r
1132 if (! tpi.OpenArchive(szFileName, llFileCount))
\r
1134 tpi.FreeLibrary();
\r
1135 * llFileCount = 0;
\r
1140 while (fs.GetNext(& szTPIName));
\r
1145 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1147 switch (nErrorCode)
\r
1149 case TPI_ERROR_SUCCESS:
\r
1150 case TPI_ERROR_S_ENDOFDATA:
\r
1151 case TPI_CALLBACK_CONTINUE:
\r
1153 case TPI_ERROR_D_UNSUPPORTED:
\r
1154 wxLogError(_("Sorry, this function is not supported yet."));
\r
1156 case TPI_ERROR_D_SKIPPED:
\r
1157 case TPI_CALLBACK_CANCEL:
\r
1158 wxLogError(_("This operation is canceled by the user."));
\r
1161 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1163 return nErrorCode;
\r