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_S_COLUMN, g_nSortColumn);
\r
89 this->conf.WriteId(CONF_LISTVIEW_S_ASCEND, g_fSortAscend);
\r
95 //******************************************************************************
\r
97 //******************************************************************************
\r
99 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
\r
100 EVT_INIT_DIALOG( MainFrame::OnInit)
\r
102 EVT_MENU(XRCID("Arc_Create"), MainFrame::OnArcCreate)
\r
103 EVT_MENU(XRCID("Arc_Open"), MainFrame::OnArcOpen)
\r
104 EVT_MENU(XRCID("Arc_Close"), MainFrame::OnArcClose)
\r
105 EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)
\r
106 EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)
\r
107 EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)
\r
108 EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)
\r
109 EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
\r
110 EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)
\r
111 EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)
\r
112 EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)
\r
113 EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)
\r
114 EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
\r
115 EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)
\r
116 EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
\r
117 EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
\r
118 EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
\r
120 EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
\r
121 EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
\r
123 EVT_LIST_ITEM_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)
\r
124 EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)
\r
126 EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
\r
129 //******************************************************************************
\r
131 //******************************************************************************
\r
133 void MainFrame::OnInit(wxInitDialogEvent&)
\r
136 this->menubar = this->GetMenuBar();
\r
137 this->toolbar = this->GetToolBar();
\r
138 this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
\r
139 this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
\r
140 this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
\r
141 this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
\r
142 this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
\r
145 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
146 wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
\r
151 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
\r
152 this->SetIcon(icon);
\r
155 this->OnArcClose(e);
\r
158 this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));
\r
161 int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);
\r
162 e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
\r
163 this->OnViewMode(e);
\r
164 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
165 this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
\r
166 this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));
\r
167 this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED, 80l));
\r
168 this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_PACKED, 80l));
\r
169 this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_RATIO, 50l));
\r
170 this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_METHOD, 60l));
\r
171 this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_ATTR, 50l));
\r
172 this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD, 150l));
\r
173 this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_PATH, 100l));
\r
174 this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_TYPE, 100l));
\r
175 this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_NO, 35l));
\r
176 g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);
\r
177 g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);
\r
178 this->list_ctrl->SetDropTarget(new myFileDropTarget(this));
\r
180 // ツールバー/ステータスバー設定。
\r
181 int nStatusBarParts[] = {70, 70, 180, 50, -1};
\r
182 this->statusbar->SetFieldsCount(5, nStatusBarParts);
\r
183 this->SetStatusBarPane(-1);
\r
184 bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);
\r
185 this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
\r
186 this->statusbar->Show(fShow);
\r
187 fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);
\r
188 this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
\r
189 this->toolbar->Show(fShow);
\r
194 void MainFrame::OnExit(wxCommandEvent&)
\r
199 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
201 TPI_SWITCHES swInfo;
\r
202 swInfo.pCustomSwitches = NULL;
\r
206 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
207 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
209 if (e.GetClientData() == NULL)
\r
212 wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
213 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
214 if (fd.ShowModal() == wxID_CANCEL)
\r
218 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
219 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
220 fd.GetFilenames(mkDlg.files);
\r
224 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
225 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
227 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
229 wxFileName fn(mkDlg.files[n]);
\r
230 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
231 mkDlg.files[n] = fn.GetFullPath();
\r
235 this->OnArcClose(e);
\r
236 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
237 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
238 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
239 this->fnArchive.SetEmptyExt();
\r
240 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
243 mkDlg.InitDialog();
\r
244 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
250 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
251 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
252 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
253 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
254 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
255 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
256 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
257 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
258 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
259 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
260 mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);
\r
263 int nSelected = mkDlg.chType->GetSelection();
\r
264 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
265 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].nTypeId))
\r
267 ::wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));
\r
272 if (! tpi.SetCallbackProc(TPICallbackProc))
\r
274 ::wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));
\r
278 ProcessDialog procDlg;
\r
279 procDlg.InitDialog();
\r
280 procDlg.Show(true);
\r
281 if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
283 this->ErrorCheck(tpi.nErrorCode);
\r
286 procDlg.Show(false);
\r
289 if (mkDlg.cbOpenAfter->IsChecked())
\r
293 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
297 if (mkDlg.cbExitAfter->IsChecked())
\r
304 this->OnArcOpen(e);
\r
307 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
310 if (e.GetId() == XRCID("Arc_Open"))
\r
312 wxFileDialog fd(this);
\r
313 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
314 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
315 if (fd.ShowModal() == wxID_CANCEL)
\r
319 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
320 this->fnArchive = wxFileName(fd.GetPath());
\r
322 this->OnArcClose(e);
\r
325 ProcessDialog procDlg;
\r
326 procDlg.InitDialog();
\r
327 procDlg.Show(true);
\r
329 // TPIを読み込み、最初のコールバックを送信。
\r
330 TPI_PROCESSINFO piInfo;
\r
331 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
332 piInfo.eStatus = 0x1000;
\r
333 piInfo.nProcessedSize = 0;
\r
334 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
335 piInfo.fiInfo.nUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
\r
336 if (piInfo.fiInfo.nUnpackedSize == 0)
\r
338 procDlg.Show(false);
\r
340 ::wxLogError(_("No plug-in supporting this archive was found!"));
\r
343 TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
346 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
349 if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
\r
351 procDlg.Show(false);
\r
353 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));
\r
358 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
359 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
360 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
362 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
363 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
364 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
365 this->tree_ctrl->SetImageList(& g_hIconT);
\r
367 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
369 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
371 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
373 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
376 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
378 piInfo.eStatus = 0x1001;
\r
381 piInfo.nProcessedSize++;
\r
382 if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
384 procDlg.Show(false);
\r
385 tpi.CloseArchive();
\r
387 this->OnArcClose(e);
\r
392 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
\r
394 // ディレクトリ属性を含むものについては除去。
\r
395 if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
402 if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
\r
404 piInfo.fiInfo.eDanger = TRUE;
\r
405 ::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
407 // 空白の連続による拡張子偽装を検査。
\r
408 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
410 piInfo.fiInfo.eDanger = TRUE;
\r
411 ::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
414 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
416 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
418 piInfo.fiInfo.eDanger = TRUE;
\r
419 ::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
423 case 0x200f: c = 0x2027; break;
\r
424 case 0x202e: c = 0x2060; break;
\r
429 this->fileinfo.Add(piInfo.fiInfo);
\r
431 while (tpi.GetFileInformation(& piInfo.fiInfo, false));
\r
434 // GetFileInformationがエラー終了した場合。
\r
435 if (tpi.nErrorCode != TPI_ERROR_S_ENDOFDATA)
\r
437 ::wxLogError(_("Error: %s!"), wxT("GetFileInformation()"));
\r
441 if (! tpi.GetArchiveInformation(& this->aiArchive))
\r
443 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));
\r
447 if (! tpi.CloseArchive())
\r
449 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));
\r
453 this->fileinfo.Shrink();
\r
454 this->tree_ctrl->ExpandAll();
\r
455 this->tree_ctrl->ScrollTo(idArchive);
\r
456 this->tree_ctrl->SelectItem(idArchive);
\r
457 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
458 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
461 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
462 this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);
\r
463 this->statusbar->SetStatusText(wxString::Format(_("%dB -> %dB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
464 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
465 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
468 SetMenuToolState("Arc_Close", true);
\r
469 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
470 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
471 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
472 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
473 SetMenuToolState("Arc_Delete", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
474 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
475 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
477 procDlg.Show(false);
\r
480 void MainFrame::OnArcClose(wxCommandEvent&)
\r
482 // ツリービュー・リストビュー設定。
\r
483 this->tree_ctrl->DeleteAllItems();
\r
484 this->list_ctrl->DeleteAllItems();
\r
485 this->list_ctrl->showFileInfo.Clear();
\r
488 SetMenuToolState("Arc_Close", false);
\r
489 SetMenuToolState("Arc_Add", false);
\r
490 SetMenuToolState("Arc_SFX", false);
\r
491 SetMenuToolState("Arc_UnSFX", false);
\r
492 SetMenuToolState("Arc_Extract", false);
\r
493 SetMenuToolState("Arc_Delete", false);
\r
494 SetMenuToolState("Arc_Test", false);
\r
495 SetMenuToolState("Arc_Repair", false);
\r
497 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
499 this->statusbar->SetStatusText(wxEmptyString, i);
\r
501 this->fileinfo.Clear();
\r
502 this->aiArchive.szComment.Empty();
\r
503 this->aiArchive.fnArchive.Clear();
\r
504 this->aiArchive.fiInfo.szTypeName.Empty();
\r
505 this->aiArchive.fiInfo.szSuffix.Empty();
\r
506 this->aiArchive.fiInfo.szEngineName.Empty();
\r
507 this->aiArchive.fiInfo.szTPIName.Empty();
\r
509 g_hIconT.RemoveAll();
\r
510 g_hIconLL.RemoveAll();
\r
511 g_hIconLS.RemoveAll();
\r
512 this->tpi.FreeLibrary();
\r
515 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
519 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
520 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
521 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
524 wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
525 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
526 if (fd.ShowModal() == wxID_CANCEL)
\r
530 fd.GetFilenames(mkDlg.files);
\r
531 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
534 mkDlg.InitDialog();
\r
535 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
541 TPI_SWITCHES swInfo;
\r
542 swInfo.pCustomSwitches = NULL;
\r
543 swInfo.fMakeSFX = false;
\r
544 swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());
\r
545 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
546 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
547 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
548 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
549 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
550 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
551 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
552 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
553 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
555 ProcessDialog procDlg;
\r
556 procDlg.InitDialog();
\r
557 procDlg.Show(true);
\r
558 if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
560 this->ErrorCheck(tpi.nErrorCode);
\r
562 procDlg.Show(false);
\r
564 if (mkDlg.cbOpenAfter->IsChecked())
\r
568 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
572 if (mkDlg.cbExitAfter->IsChecked())
\r
578 // 終了しない場合は書庫を再読み込み。
\r
579 this->OnArcOpen(e);
\r
582 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
584 TPI_SWITCHES swInfo;
\r
585 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
588 wxFileDialog fd(this, swInfo.fMakeSFX ? _("Save as SFX") : _("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString));
\r
589 fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
590 if (fd.ShowModal() == wxID_CANCEL)
\r
594 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
595 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
597 wxArrayString files;
\r
598 files.Add(fd.GetPath());
\r
600 ProcessDialog procDlg;
\r
601 procDlg.InitDialog();
\r
602 procDlg.Show(true);
\r
603 if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
\r
605 this->ErrorCheck(tpi.nErrorCode);
\r
607 procDlg.Show(false);
\r
610 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
612 TPI_SWITCHES swInfo;
\r
613 swInfo.pCustomSwitches = NULL;
\r
615 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。
\r
616 int nMode = e.GetInt();
\r
618 wxFileType * ftFile = NULL;
\r
620 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
622 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
623 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
624 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
625 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
632 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
635 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。
\r
636 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
639 ::wxLogError(_("Unable to get the file type!"));
\r
646 swInfo.fStoreDirectoryPathes = false;
\r
647 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
648 if (szDestDirBase == wxT("-----"))
\r
650 // 書庫ルートのときは書庫名にしておく。
\r
651 szDestDirBase = this->fnArchive.GetName();
\r
653 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
\r
654 if (! swInfo.fnDestinationDirectory.IsOk())
\r
656 ::wxLogError(_("Unable to make the temporary directory!"));
\r
662 mkDlg.InitDialog();
\r
663 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
669 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
670 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
671 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
672 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
674 // 必要なら書庫名でディレクトリを作成する。
\r
675 if (WillMakeDirByArcName(this, & mkDlg))
\r
677 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
678 if (! swInfo.fnDestinationDirectory.IsOk())
\r
680 ::wxLogError(_("Unable to make the destination directory!"));
\r
686 ProcessDialog procDlg;
\r
687 procDlg.InitDialog();
\r
688 procDlg.Show(true);
\r
689 if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
691 this->ErrorCheck(tpi.nErrorCode);
\r
693 procDlg.Show(false);
\r
697 if (mkDlg.cbOpenAfter->IsChecked())
\r
701 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
705 if (mkDlg.cbExitAfter->IsChecked())
\r
713 wxArrayString asFiles;
\r
717 asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName());
\r
718 if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
\r
721 // Linuxでは引用符で囲む必要がある。
\r
722 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
\r
724 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
\r
731 wxFileDataObject objFile;
\r
732 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
734 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
738 objFile.AddFile(szFileName);
\r
740 asFiles.Add(szFileName);
\r
744 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
\r
748 wxDropSource dropSource(objFile, this);
\r
749 if (dropSource.DoDragDrop() != wxDragMove)
\r
752 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
758 // ファイルと一時ディレクトリを削除。
\r
759 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
761 ::wxRemoveFile(asFiles[i]);
\r
763 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
\r
767 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
769 // 全ファイル削除は危険ではないかと。
\r
770 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
775 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
781 TPI_SWITCHES swInfo;
\r
782 ProcessDialog procDlg;
\r
783 procDlg.InitDialog();
\r
784 procDlg.Show(true);
\r
785 if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
787 this->ErrorCheck(tpi.nErrorCode);
\r
789 procDlg.Show(false);
\r
792 this->OnArcOpen(e);
\r
795 void MainFrame::OnArcTest(wxCommandEvent&)
\r
797 TPI_SWITCHES swInfo;
\r
798 ProcessDialog procDlg;
\r
799 procDlg.InitDialog();
\r
800 procDlg.Show(true);
\r
801 bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));
\r
802 procDlg.Show(false);
\r
805 ::wxLogMessage(_("This is a correct archive."));
\r
809 this->ErrorCheck(tpi.nErrorCode);
\r
813 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
815 TPI_SWITCHES swInfo;
\r
816 ProcessDialog procDlg;
\r
817 procDlg.InitDialog();
\r
818 procDlg.Show(true);
\r
819 if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
821 this->ErrorCheck(tpi.nErrorCode);
\r
823 procDlg.Show(false);
\r
826 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
829 this->menubar->Check(n, true);
\r
830 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
831 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
832 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
835 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
837 this->toolbar->Show(e.IsChecked());
\r
840 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
842 this->statusbar->Show(e.IsChecked());
\r
845 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
847 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
849 this->list_ctrl->Select(i, true);
\r
855 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
858 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
860 this->list_ctrl->showFileInfo.Clear();
\r
861 this->list_ctrl->DeleteAllItems();
\r
862 g_hIconLL.RemoveAll();
\r
863 g_hIconLS.RemoveAll();
\r
865 // 現在のアイテムの選択状態を無効にしておく。
\r
866 long nSelected = this->list_ctrl->GetFirstSelected();
\r
867 while (nSelected != -1)
\r
869 this->list_ctrl->Select(nSelected, false);
\r
870 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
874 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
875 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
877 // 配列と比較し、パスが一致しなければ消す。
\r
878 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
881 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
884 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
890 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
895 this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
\r
900 this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
\r
901 this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
\r
904 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
906 // TODO : アイテムが子階層を持っていても展開できない。
\r
907 this->tree_ctrl->SelectItem(e.GetItem());
\r
911 this->OnArcExtract(e1);
\r
916 void MainFrame::OnListItemDClick(wxListEvent&)
\r
920 this->OnArcExtract(e);
\r
923 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
925 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
927 // アイテムを選択せずドラッグしようとした場合。
\r
933 this->OnArcExtract(e);
\r
938 void MainFrame::OnFilter(wxCommandEvent&)
\r
941 e.SetItem(this->tree_ctrl->GetSelection());
\r
942 this->OnTreeChanged(e);
\r
947 wxULongLong_t MainFrame::LoadTPI(wxString szFileName)
\r
950 wxDir fs(L_DIR_B_LIB);
\r
951 wxULongLong_t llFileCount = 0;
\r
952 wxString szTPIName;
\r
953 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
958 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, 0))
\r
965 tpi.SetCallbackProc(TPICallbackProc);
\r
968 if (! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)
\r
976 while (fs.GetNext(& szTPIName));
\r
978 return llFileCount;
\r
981 int MainFrame::ErrorCheck(int nErrorCode)
\r
983 switch (nErrorCode)
\r
985 case TPI_ERROR_SUCCESS:
\r
986 case TPI_CALLBACK_CONTINUE:
\r
988 case TPI_ERROR_D_UNSUPPORTED:
\r
989 ::wxLogError(_("Sorry, this function is not supported yet."));
\r
991 case TPI_ERROR_D_SKIPPED:
\r
992 case TPI_CALLBACK_CANCEL:
\r
993 ::wxLogError(_("This operation is canceled by the user."));
\r
996 ::wxLogError(_("Error code: %d"), nErrorCode);
\r