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(), gFrame(NULL)
\r
52 MainFrame::~MainFrame()
\r
55 if (! this->IsIconized() && ! this->IsMaximized())
\r
58 this->GetSize(& a, & b);
\r
59 this->conf.WriteId(CONF_WINDOW_WIDTH, a);
\r
60 this->conf.WriteId(CONF_WINDOW_HEIGHT, b);
\r
61 this->GetPosition(& a, & b);
\r
62 this->conf.WriteId(CONF_WINDOW_X, a);
\r
63 this->conf.WriteId(CONF_WINDOW_Y, b);
\r
65 this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());
\r
68 this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());
\r
69 this->conf.WriteId(CONF_WINDOW_TOOLBAR, this->toolbar->IsShown());
\r
72 this->conf.WriteId(CONF_LISTVIEW_SHOWMODE, this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);
\r
73 if (this->menubar->IsChecked(XRCID("Exe_View_Details")))
\r
75 this->conf.WriteId(CONF_LISTVIEW_C_FILENAME, this->list_ctrl->GetColumnWidth(0));
\r
76 this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED, this->list_ctrl->GetColumnWidth(1));
\r
77 this->conf.WriteId(CONF_LISTVIEW_C_PACKED, this->list_ctrl->GetColumnWidth(2));
\r
78 this->conf.WriteId(CONF_LISTVIEW_C_RATIO, this->list_ctrl->GetColumnWidth(3));
\r
79 this->conf.WriteId(CONF_LISTVIEW_C_METHOD, this->list_ctrl->GetColumnWidth(4));
\r
80 this->conf.WriteId(CONF_LISTVIEW_C_ATTR, this->list_ctrl->GetColumnWidth(5));
\r
81 this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD, this->list_ctrl->GetColumnWidth(6));
\r
82 this->conf.WriteId(CONF_LISTVIEW_C_PATH, this->list_ctrl->GetColumnWidth(7));
\r
83 this->conf.WriteId(CONF_LISTVIEW_C_TYPE, this->list_ctrl->GetColumnWidth(8));
\r
84 this->conf.WriteId(CONF_LISTVIEW_C_NO, this->list_ctrl->GetColumnWidth(9));
\r
85 this->conf.WriteId(CONF_LISTVIEW_C_COMMENT, this->list_ctrl->GetColumnWidth(10));
\r
86 this->conf.WriteId(CONF_LISTVIEW_S_COLUMN, g_nSortColumn);
\r
87 this->conf.WriteId(CONF_LISTVIEW_S_ASCEND, g_fSortAscend);
\r
91 delete this->gFrame;
\r
93 this->OnArcClose(e);
\r
96 //******************************************************************************
\r
98 //******************************************************************************
\r
100 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
\r
101 EVT_INIT_DIALOG(MainFrame::OnInit)
\r
102 EVT_SIZE( MainFrame::OnSize)
\r
103 EVT_CLOSE( MainFrame::OnClose)
\r
105 EVT_MENU(XRCID("Arc_Create"), MainFrame::OnArcCreate)
\r
106 EVT_MENU(XRCID("Arc_Open"), MainFrame::OnArcOpen)
\r
107 EVT_MENU(XRCID("Arc_Close"), MainFrame::OnArcClose)
\r
108 EVT_MENU(XRCID("Arc_Clone"), MainFrame::OnArcClone)
\r
109 EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)
\r
110 EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)
\r
111 EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)
\r
112 EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)
\r
113 EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
\r
114 EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)
\r
115 EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)
\r
116 EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)
\r
117 EVT_MENU(XRCID("Exe_Copy"), MainFrame::OnExeCopy)
\r
118 EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)
\r
119 EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
\r
120 EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)
\r
121 EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
\r
122 EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
\r
123 EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
\r
125 EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
\r
126 EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
\r
127 EVT_COMMAND_CONTEXT_MENU(XRCID("TreeView"), MainFrame::OnContextMenu)
\r
129 EVT_LIST_ITEM_SELECTED( XRCID("ListView"), MainFrame::OnListItemSelect)
\r
130 EVT_LIST_ITEM_DESELECTED(XRCID("ListView"), MainFrame::OnListItemSelect)
\r
131 EVT_LIST_ITEM_ACTIVATED( XRCID("ListView"), MainFrame::OnListItemDClick)
\r
132 EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)
\r
133 EVT_COMMAND_CONTEXT_MENU(XRCID("ListView"), MainFrame::OnContextMenu)
\r
135 EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
\r
138 //******************************************************************************
\r
140 //******************************************************************************
\r
142 void MainFrame::OnInit(wxInitDialogEvent&)
\r
145 this->menubar = this->GetMenuBar();
\r
146 this->toolbar = this->GetToolBar();
\r
147 this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
\r
148 this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
\r
149 this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
\r
150 this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
\r
151 this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
\r
154 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
155 wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
\r
160 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
\r
161 this->SetIcon(icon);
\r
164 this->OnArcClose(e);
\r
165 this->SetDropTarget(new myFileDropTarget(this));
\r
168 this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));
\r
171 int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);
\r
172 e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
\r
173 this->OnViewMode(e);
\r
174 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
175 this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
\r
176 this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));
\r
177 this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED, 80l));
\r
178 this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_PACKED, 80l));
\r
179 this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_RATIO, 50l));
\r
180 this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_METHOD, 60l));
\r
181 this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_ATTR, 50l));
\r
182 this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD, 150l));
\r
183 this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_PATH, 100l));
\r
184 this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_TYPE, 100l));
\r
185 this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_NO, 35l));
\r
186 this->list_ctrl->InsertColumn(10,_("Comment"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_COMMENT, 35l));
\r
187 g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);
\r
188 g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);
\r
190 // ツールバー/ステータスバー設定。
\r
191 int nStatusBarParts[] = {70, 70, 180, 50, -1};
\r
192 this->statusbar->SetFieldsCount(5, nStatusBarParts);
\r
193 this->SetStatusBarPane(-1);
\r
194 bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);
\r
195 this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
\r
196 this->statusbar->Show(fShow);
\r
197 fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);
\r
198 this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
\r
199 this->toolbar->Show(fShow);
\r
201 // ステータスバー上にプログレスバーを作成。
\r
202 this->gFrame = new wxGauge(this, -1, 0, wxPoint(0, 0), wxSize(200, 10));
\r
203 this->gFrame->Show(false);
\r
206 void MainFrame::OnClose(wxCloseEvent& e)
\r
208 if (e.CanVeto() && g_procDlg != NULL)
\r
210 g_procDlg->OnClose(e);
\r
219 void MainFrame::OnSize(wxSizeEvent& e)
\r
222 if (this->window_splitter != NULL)
\r
224 this->window_splitter->SetSize(this->GetClientSize());
\r
228 if (this->gFrame != NULL)
\r
230 wxPoint p = this->statusbar->GetPosition();
\r
231 wxSize s = this->GetSize();
\r
232 p.x += s.GetWidth() - 230;
\r
234 this->gFrame->SetPosition(p);
\r
241 void MainFrame::OnExit(wxCommandEvent&)
\r
246 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
248 TPI_SWITCHES swInfo;
\r
249 swInfo.pCustomSwitches = NULL;
\r
252 MakeDialog mkDlg(this, TPI_COMMAND_CREATE);
\r
253 if (e.GetClientData() == NULL)
\r
256 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
257 if (fd.ShowModal() == wxID_CANCEL)
\r
261 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
262 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
263 fd.GetFilenames(mkDlg.files);
\r
267 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
268 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
270 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
272 wxFileName fn(mkDlg.files[n]);
\r
273 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
274 mkDlg.files[n] = fn.GetFullPath();
\r
278 this->OnArcClose(e);
\r
279 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
280 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
281 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
282 this->fnArchive.SetEmptyExt();
\r
283 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
286 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
292 int nSelected = mkDlg.chType->GetSelection();
\r
293 swInfo.nArchiveType = mkDlg.afInfo[nSelected].nTypeId;
\r
294 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
295 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
296 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
297 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
298 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
299 swInfo.fCompressHeader = mkDlg.cbCompressHeader->IsChecked();
\r
300 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
301 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
302 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
303 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
304 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
305 mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);
\r
308 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
309 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), TPICallbackProc, mkDlg.afInfo[nSelected].nTypeId))
\r
311 this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));
\r
317 ProcessDialog procDlg(this, mkDlg.files.GetCount());
\r
318 tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
319 procDlg.Show(false);
\r
320 if (this->ErrorCheck(tpi.nErrorCode) != TPI_ERROR_SUCCESS)
\r
327 if (mkDlg.cbOpenAfter->IsChecked())
\r
330 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
333 if (mkDlg.cbExitAfter->IsChecked())
\r
340 if (this->fnArchive.FileExists())
\r
342 this->OnArcOpen(e);
\r
346 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
348 // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。
\r
349 int nMode = e.GetInt();
\r
354 wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
355 if (fd.ShowModal() == wxID_CANCEL)
\r
359 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
360 this->fnArchive = wxFileName(fd.GetPath());
\r
364 ProcessDialog procDlg(this);
\r
365 TPI_PROCESSINFO piInfo;
\r
366 piInfo.fiInfo.nUnpackedSize = 0;
\r
367 if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))
\r
372 this->OnArcCreate(e);
\r
374 else if (this->IsShown())
\r
377 this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);
\r
381 wxLogError(_("No plug-in supporting this archive was found!"));
\r
387 // コマンドラインから書庫を開く場合にはウインドウが表示されていないので表示。
\r
388 if (! this->IsShown())
\r
393 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
394 piInfo.eStatus = 0x1001;
\r
395 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
397 procDlg.Show(false);
\r
398 tpi.CloseArchive();
\r
399 // OnArcClose処理はProcessDialogのデストラクタで行う。
\r
400 // this->OnArcClose(e);
\r
405 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
408 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
409 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
410 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
412 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
413 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
414 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
415 this->tree_ctrl->SetImageList(& g_hIconT);
\r
417 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
418 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(myRescaleIcon(GetFileTypeIcon(this->fnArchive)))),
\r
419 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
421 // 巨大書庫のときにファイル名検査を省略するか。
\r
422 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
425 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
427 piInfo.eStatus = 0x1002;
\r
428 piInfo.nProcessedSize = 0;
\r
431 piInfo.nProcessedSize++;
\r
432 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
434 procDlg.Show(false);
\r
435 tpi.CloseArchive();
\r
436 // OnArcClose処理はProcessDialogのデストラクタで行う。
\r
437 // this->OnArcClose(e);
\r
442 if (piInfo.fiInfo.szStoredName.IsEmpty())
\r
444 piInfo.fiInfo.szStoredName = this->fnArchive.GetName();
\r
445 if (piInfo.fiInfo.fnFileName.HasExt())
\r
447 piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();
\r
449 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
454 wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);
\r
455 if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))
\r
457 piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);
\r
460 if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))
\r
466 if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND
\r
467 || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND
\r
468 || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)
\r
470 wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();
\r
471 sz.Replace(wxT("\r"), wxT(" "));
\r
472 sz.Replace(wxT("\n"), wxT(" "));
\r
473 sz.Replace(wxT("\t"), wxT(" "));
\r
474 piInfo.fiInfo.eDanger = TRUE;
\r
475 piInfo.fiInfo.fnFileName = wxFileName(sz);
\r
476 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
482 if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
484 piInfo.fiInfo.eDanger = TRUE;
\r
485 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
487 // 空白の連続による拡張子偽装を検査。
\r
488 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
490 piInfo.fiInfo.eDanger = TRUE;
\r
491 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
494 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
496 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
498 piInfo.fiInfo.eDanger = TRUE;
\r
499 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
503 case 0x200f: c = 0x2027; break;
\r
504 case 0x202e: c = 0x2060; break;
\r
510 bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;
\r
511 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);
\r
513 // ディレクトリ属性を含むものについては情報を保存しない。
\r
520 this->fileinfo.Add(piInfo.fiInfo);
\r
522 while (tpi.GetFileInformation(& piInfo.fiInfo));
\r
525 // GetFileInformationがエラー終了した場合。
\r
526 this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));
\r
529 tpi.GetArchiveInformation(& this->aiArchive);
\r
530 this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));
\r
531 this->szPassword = procDlg.szPassword;
\r
534 tpi.CloseArchive();
\r
535 this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));
\r
538 this->fileinfo.Shrink();
\r
539 if (this->fileinfo.Count() < 10000)
\r
541 this->tree_ctrl->ExpandAll();
\r
542 this->tree_ctrl->SelectItem(idArchive);
\r
546 // ファイル数が多いとソートに時間がかかるので、書庫のルートを表示させる。
\r
547 this->tree_ctrl->Expand(idArcRoot);
\r
548 this->tree_ctrl->SelectItem(idArcRoot);
\r
551 this->tree_ctrl->ScrollTo(idArchive);
\r
552 this->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);
\r
553 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
554 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
557 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
558 this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);
\r
559 this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
560 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
561 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
562 this->statusbar->SetToolTip(
\r
564 _("%s(%s)\nTPI: %s(%s)\nAccess: %s\nModify: %s\nCreate: %s\nComment:\n%s"),
\r
565 this->fnArchive.GetFullName().c_str(), this->aiArchive.fiInfo.szTypeName.c_str(),
\r
566 this->aiArchive.fiInfo.szTPIName.c_str(), this->aiArchive.fiInfo.szEngineName.c_str(),
\r
567 this->aiArchive.tmAccess.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
568 this->aiArchive.tmModify.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
569 this->aiArchive.tmCreate.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
570 this->aiArchive.szComment.c_str()
\r
574 // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。
\r
575 SetMenuToolState("Arc_Close", true);
\r
576 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
577 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
578 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
579 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
580 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
581 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
582 this->menubar->Enable(XRCID("Arc_Clone"), true);
\r
584 procDlg.Show(false);
\r
588 void MainFrame::OnArcClose(wxCommandEvent& e)
\r
590 // ツリービュー・リストビュー設定。
\r
591 this->tree_ctrl->DeleteAllItems();
\r
592 this->list_ctrl->DeleteAllItems();
\r
593 this->list_ctrl->apShowFile.Clear();
\r
596 SetMenuToolState("Arc_Close", false);
\r
597 SetMenuToolState("Arc_Add", false);
\r
598 SetMenuToolState("Arc_SFX", false);
\r
599 SetMenuToolState("Arc_UnSFX", false);
\r
600 SetMenuToolState("Arc_Extract", false);
\r
601 SetMenuToolState("Arc_Delete", false);
\r
602 SetMenuToolState("Arc_Test", false);
\r
603 SetMenuToolState("Arc_Repair", false);
\r
604 this->menubar->Enable(XRCID("Arc_Clone"), false);
\r
606 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
608 this->statusbar->SetStatusText(wxEmptyString, i);
\r
610 this->statusbar->SetToolTip(wxEmptyString);
\r
611 this->fileinfo.Clear();
\r
612 this->szPassword.Empty();
\r
613 this->aiArchive.szComment.Empty();
\r
614 this->aiArchive.fnArchive.Clear();
\r
615 this->aiArchive.fiInfo.szTypeName.Empty();
\r
616 this->aiArchive.fiInfo.szSuffix.Empty();
\r
617 this->aiArchive.fiInfo.szEngineName.Empty();
\r
618 this->aiArchive.fiInfo.szTPIName.Empty();
\r
620 g_hIconT.RemoveAll();
\r
621 g_hIconLL.RemoveAll();
\r
622 g_hIconLS.RemoveAll();
\r
624 // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。
\r
625 if (e.GetExtraLong() == 0)
\r
631 void MainFrame::OnArcClone(wxCommandEvent&)
\r
634 wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
635 if (fd.ShowModal() == wxID_CANCEL)
\r
639 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
642 ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());
\r
643 wxFileName fn(fd.GetPath());
\r
644 wxDateTime dtAccess, dtModify, dtCreate;
\r
645 this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);
\r
646 fn.SetTimes(& dtAccess, & dtModify, & dtCreate);
\r
649 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
652 MakeDialog mkDlg(this, TPI_COMMAND_ADD);
\r
654 TPI_SWITCHES swInfo;
\r
655 swInfo.pCustomSwitches = NULL;
\r
657 if (e.GetClientData() == NULL)
\r
659 if (::wxGetKeyState(WXK_SHIFT))
\r
662 wxDirDialog dd(this, _("Choose dir to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);
\r
663 if (dd.ShowModal() == wxID_CANCEL)
\r
667 swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());
\r
668 this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());
\r
669 mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());
\r
674 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
675 if (fd.ShowModal() == wxID_CANCEL)
\r
679 fd.GetFilenames(mkDlg.files);
\r
680 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
681 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
686 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
687 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
689 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
691 wxFileName fn(mkDlg.files[n]);
\r
692 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
693 mkDlg.files[n] = fn.GetFullPath();
\r
698 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
704 swInfo.fMakeSFX = false;
\r
705 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
706 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
707 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
708 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
709 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
710 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
711 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
712 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
713 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
717 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
718 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
719 this->ErrorCheck(tpi.nErrorCode);
\r
720 procDlg.Show(false);
\r
723 if (mkDlg.cbOpenAfter->IsChecked())
\r
726 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
729 if (mkDlg.cbExitAfter->IsChecked())
\r
735 // 終了しない場合は書庫を再読み込み。
\r
736 this->OnArcOpen(e);
\r
739 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
741 TPI_SWITCHES swInfo;
\r
742 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
745 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
746 if (fd.ShowModal() == wxID_CANCEL)
\r
750 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
751 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
753 wxArrayString files;
\r
754 files.Add(fd.GetPath());
\r
756 ProcessDialog procDlg(this);
\r
757 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
758 this->ErrorCheck(tpi.nErrorCode);
\r
759 procDlg.Show(false);
\r
762 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
764 TPI_SWITCHES swInfo;
\r
765 swInfo.pCustomSwitches = NULL;
\r
766 swInfo.szPassword = this->szPassword;
\r
768 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
769 int nMode = e.GetInt();
\r
770 if (e.GetInt() == 8)
\r
775 wxFileType * ftFile = NULL;
\r
777 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
778 MakeDialog mkDlg(this, TPI_COMMAND_EXTRACT);
\r
779 mkDlg.files = MakeTargetFileList(this, nMode == 1, nMode == 0);
\r
781 bool bMakeDir = false;
\r
785 swInfo.fStoreDirectoryPathes = false;
\r
786 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
787 if (szDestDirBase == wxT("-----"))
\r
789 // 書庫ルートのときは書庫名にしておく。
\r
790 szDestDirBase = this->fnArchive.GetName();
\r
792 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(wxStandardPaths::Get().GetTempDir()), szDestDirBase, true);
\r
793 if (! swInfo.fnDestinationDirectory.IsOk())
\r
795 wxLogError(_("Unable to make the temporary directory!"));
\r
801 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
807 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
808 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
809 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
810 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
812 // 必要なら書庫名でディレクトリを作成する。
\r
813 bMakeDir = WillMakeDirByArcName(this, & mkDlg);
\r
816 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
817 if (! swInfo.fnDestinationDirectory.IsOk())
\r
819 wxLogError(_("Unable to make the destination directory!"));
\r
827 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
828 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
829 this->ErrorCheck(tpi.nErrorCode);
\r
830 procDlg.Show(false);
\r
835 if (mkDlg.cbOpenAfter->IsChecked())
\r
838 if (mkDlg.chDirMake->GetSelection() == 2 && ! bMakeDir)
\r
840 wxTreeItemId tiArcSub = this->tree_ctrl->GetLastChild(this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()));
\r
841 if (tiArcSub.IsOk())
\r
843 swInfo.fnDestinationDirectory.SetFullName(this->tree_ctrl->GetItemText(tiArcSub));
\r
846 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
849 if (mkDlg.cbExitAfter->IsChecked())
\r
860 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
861 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
863 // 種類が取得できないときはテキストとみなす。
\r
864 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
868 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
869 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
870 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
874 // Linuxでは引用符で囲む必要がある。
\r
875 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
877 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
882 pCallback->OnTerminate(0, 0);
\r
888 wxArrayString asFiles;
\r
889 myFileDataObject * objFile = new myFileDataObject();
\r
890 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
891 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
893 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
896 asFiles.Add(szFileName);
\r
901 objFile->AddFile(szFileName);
\r
906 objFile->AddFile(objFile->szTempDir);
\r
911 wxTheClipboard->SetData(objFile);
\r
915 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
916 this->SetDropTarget(NULL);
\r
919 wxDropSource dropSource(* objFile, this);
\r
920 wxDragResult drResult = dropSource.DoDragDrop();
\r
921 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
924 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
928 this->SetDropTarget(new myFileDropTarget(this));
\r
930 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
933 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
935 chmod(asFiles[i].ToUTF8(), 0600);
\r
936 ::wxRemoveFile(asFiles[i]);
\r
946 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
948 // 全ファイル削除は危険ではないかと。
\r
949 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
951 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
952 SetMenuToolState("Arc_Delete", false);
\r
956 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
963 wxArrayString asFiles = MakeTargetFileList(this);
\r
964 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
965 TPI_SWITCHES swInfo;
\r
966 swInfo.szPassword = this->szPassword;
\r
967 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
968 this->ErrorCheck(tpi.nErrorCode);
\r
969 procDlg.Show(false);
\r
973 this->OnArcOpen(e);
\r
976 void MainFrame::OnArcTest(wxCommandEvent&)
\r
979 wxArrayString asFiles = MakeTargetFileList(this);
\r
980 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
981 TPI_SWITCHES swInfo;
\r
982 swInfo.szPassword = this->szPassword;
\r
983 tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
984 this->ErrorCheck(tpi.nErrorCode);
\r
985 procDlg.Show(false);
\r
988 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
991 wxArrayString asFiles = MakeTargetFileList(this);
\r
992 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
993 TPI_SWITCHES swInfo;
\r
994 swInfo.szPassword = this->szPassword;
\r
995 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
996 this->ErrorCheck(tpi.nErrorCode);
\r
997 procDlg.Show(false);
\r
1000 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
1002 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1004 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
1005 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
1009 if (! wxTheClipboard->Open())
\r
1015 this->OnArcExtract(e);
\r
1016 wxTheClipboard->Close();
\r
1019 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
1021 int n = e.GetId();
\r
1022 this->menubar->Check(n, true);
\r
1023 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
1024 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
1025 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
1028 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
1030 this->toolbar->Show(e.IsChecked());
\r
1033 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
1035 this->statusbar->Show(e.IsChecked());
\r
1038 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
1040 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
1042 this->list_ctrl->Select(i, true);
\r
1048 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1051 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1053 this->list_ctrl->apShowFile.Clear();
\r
1054 this->list_ctrl->DeleteAllItems();
\r
1055 g_hIconLL.RemoveAll();
\r
1056 g_hIconLS.RemoveAll();
\r
1058 // 現在のアイテムの選択状態を無効にしておく。
\r
1059 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1060 while (nSelected != -1)
\r
1062 this->list_ctrl->Select(nSelected, false);
\r
1063 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1067 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1068 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1070 // 配列と比較し、パスが一致しなければ消す。
\r
1071 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1074 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1076 // 項目がフォルダであるなら無視。
\r
1077 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
1082 // フィルタにかからなければ無視。
\r
1083 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1088 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1093 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1094 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1097 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1099 // TODO : アイテムが子階層を持っていても展開できない。
\r
1100 this->tree_ctrl->SelectItem(e.GetItem());
\r
1102 wxCommandEvent e1;
\r
1104 this->OnArcExtract(e1);
\r
1107 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1109 wxPoint p = e.GetPosition();
\r
1110 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1115 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1117 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1118 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1119 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1120 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1123 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1127 this->OnArcExtract(e);
\r
1130 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1132 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1134 // アイテムを選択せずドラッグしようとした場合。
\r
1140 this->OnArcExtract(e);
\r
1145 void MainFrame::OnFilter(wxCommandEvent&)
\r
1148 e.SetItem(this->tree_ctrl->GetSelection());
\r
1149 this->OnTreeChanged(e);
\r
1154 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1156 // 書庫を開いていれば閉じておく。
\r
1158 this->OnArcClose(e);
\r
1161 wxDir fs(L_DIR_B_LIB);
\r
1162 wxString szTPIName;
\r
1163 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1168 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc) || ! tpi.OpenArchive(szFileName, llFileCount))
\r
1170 tpi.FreeLibrary();
\r
1171 * llFileCount = 0;
\r
1176 while (fs.GetNext(& szTPIName));
\r
1181 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1183 switch (nErrorCode)
\r
1185 case TPI_ERROR_SUCCESS:
\r
1186 case TPI_ERROR_S_ENDOFDATA:
\r
1187 case TPI_CALLBACK_CONTINUE:
\r
1189 case TPI_ERROR_D_UNSUPPORTED:
\r
1190 wxLogError(_("Sorry, this function is not supported yet."));
\r
1192 case TPI_ERROR_D_SKIPPED:
\r
1193 case TPI_CALLBACK_CANCEL:
\r
1196 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1198 return nErrorCode;
\r