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 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
249 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
250 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
251 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
252 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
253 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
254 swInfo.fCompressHeader = mkDlg.cbCompressHeader->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.Show(true);
\r
280 if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
282 this->ErrorCheck(tpi.nErrorCode);
\r
285 procDlg.Show(false);
\r
288 if (mkDlg.cbOpenAfter->IsChecked())
\r
292 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
296 if (mkDlg.cbExitAfter->IsChecked())
\r
303 this->OnArcOpen(e);
\r
306 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
309 if (e.GetId() == XRCID("Arc_Open"))
\r
311 wxFileDialog fd(this);
\r
312 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
313 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
314 if (fd.ShowModal() == wxID_CANCEL)
\r
318 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
319 this->fnArchive = wxFileName(fd.GetPath());
\r
321 this->OnArcClose(e);
\r
324 ProcessDialog procDlg;
\r
325 procDlg.Show(true);
\r
327 // TPIを読み込み、最初のコールバックを送信。
\r
328 TPI_PROCESSINFO piInfo;
\r
329 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
330 piInfo.eStatus = 0x1000;
\r
331 piInfo.nProcessedSize = 0;
\r
332 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
333 piInfo.fiInfo.nUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
\r
334 if (piInfo.fiInfo.nUnpackedSize == 0)
\r
336 procDlg.Show(false);
\r
338 ::wxLogError(_("No plug-in supporting this archive was found!"));
\r
341 TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
344 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
347 if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
\r
349 procDlg.Show(false);
\r
351 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));
\r
356 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
357 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
358 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
360 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
361 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
362 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
363 this->tree_ctrl->SetImageList(& g_hIconT);
\r
365 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
367 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
369 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
371 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
374 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
376 piInfo.eStatus = 0x1001;
\r
379 piInfo.nProcessedSize++;
\r
380 if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
382 procDlg.Show(false);
\r
383 tpi.CloseArchive();
\r
385 this->OnArcClose(e);
\r
390 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
\r
392 // ディレクトリ属性を含むものについては除去。
\r
393 if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
400 if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
\r
402 piInfo.fiInfo.eDanger = TRUE;
\r
403 ::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
405 // 空白の連続による拡張子偽装を検査。
\r
406 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
408 piInfo.fiInfo.eDanger = TRUE;
\r
409 ::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
412 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
414 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
416 piInfo.fiInfo.eDanger = TRUE;
\r
417 ::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
421 case 0x200f: c = 0x2027; break;
\r
422 case 0x202e: c = 0x2060; break;
\r
427 this->fileinfo.Add(piInfo.fiInfo);
\r
429 while (tpi.GetFileInformation(& piInfo.fiInfo, false));
\r
432 // GetFileInformationがエラー終了した場合。
\r
433 if (tpi.nErrorCode != TPI_ERROR_S_ENDOFDATA)
\r
435 ::wxLogError(_("Error: %s!"), wxT("GetFileInformation()"));
\r
439 if (! tpi.GetArchiveInformation(& this->aiArchive))
\r
441 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));
\r
445 if (! tpi.CloseArchive())
\r
447 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));
\r
451 this->fileinfo.Shrink();
\r
452 this->tree_ctrl->ExpandAll();
\r
453 this->tree_ctrl->ScrollTo(idArchive);
\r
454 this->tree_ctrl->SelectItem(idArchive);
\r
455 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
456 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
459 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
460 this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);
\r
461 this->statusbar->SetStatusText(wxString::Format(_("%dB -> %dB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
462 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
463 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
466 SetMenuToolState("Arc_Close", true);
\r
467 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
468 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
469 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
470 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
471 SetMenuToolState("Arc_Delete", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
472 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
473 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
475 procDlg.Show(false);
\r
478 void MainFrame::OnArcClose(wxCommandEvent&)
\r
480 // ツリービュー・リストビュー設定。
\r
481 this->tree_ctrl->DeleteAllItems();
\r
482 this->list_ctrl->DeleteAllItems();
\r
483 this->list_ctrl->showFileInfo.Clear();
\r
486 SetMenuToolState("Arc_Close", false);
\r
487 SetMenuToolState("Arc_Add", false);
\r
488 SetMenuToolState("Arc_SFX", false);
\r
489 SetMenuToolState("Arc_UnSFX", false);
\r
490 SetMenuToolState("Arc_Extract", false);
\r
491 SetMenuToolState("Arc_Delete", false);
\r
492 SetMenuToolState("Arc_Test", false);
\r
493 SetMenuToolState("Arc_Repair", false);
\r
495 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
497 this->statusbar->SetStatusText(wxEmptyString, i);
\r
499 this->fileinfo.Clear();
\r
500 this->aiArchive.szComment.Empty();
\r
501 this->aiArchive.fnArchive.Clear();
\r
502 this->aiArchive.fiInfo.szTypeName.Empty();
\r
503 this->aiArchive.fiInfo.szSuffix.Empty();
\r
504 this->aiArchive.fiInfo.szEngineName.Empty();
\r
505 this->aiArchive.fiInfo.szTPIName.Empty();
\r
507 g_hIconT.RemoveAll();
\r
508 g_hIconLL.RemoveAll();
\r
509 g_hIconLS.RemoveAll();
\r
510 this->tpi.FreeLibrary();
\r
513 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
517 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
518 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
519 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
522 wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
523 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
524 if (fd.ShowModal() == wxID_CANCEL)
\r
528 fd.GetFilenames(mkDlg.files);
\r
529 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
532 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
538 TPI_SWITCHES swInfo;
\r
539 swInfo.pCustomSwitches = NULL;
\r
540 swInfo.fMakeSFX = false;
\r
541 swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());
\r
542 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
543 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
544 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
545 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
546 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
547 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
548 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
549 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
550 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
552 ProcessDialog procDlg;
\r
553 procDlg.Show(true);
\r
554 if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
556 this->ErrorCheck(tpi.nErrorCode);
\r
558 procDlg.Show(false);
\r
560 if (mkDlg.cbOpenAfter->IsChecked())
\r
564 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
568 if (mkDlg.cbExitAfter->IsChecked())
\r
574 // 終了しない場合は書庫を再読み込み。
\r
575 this->OnArcOpen(e);
\r
578 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
580 TPI_SWITCHES swInfo;
\r
581 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
584 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
585 fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
586 if (fd.ShowModal() == wxID_CANCEL)
\r
590 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
591 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
593 wxArrayString files;
\r
594 files.Add(fd.GetPath());
\r
596 ProcessDialog procDlg;
\r
597 procDlg.Show(true);
\r
598 if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
\r
600 this->ErrorCheck(tpi.nErrorCode);
\r
602 procDlg.Show(false);
\r
605 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
607 TPI_SWITCHES swInfo;
\r
608 swInfo.pCustomSwitches = NULL;
\r
610 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。
\r
611 int nMode = e.GetInt();
\r
613 wxFileType * ftFile = NULL;
\r
615 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
617 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
618 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
619 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
620 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
627 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
630 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。
\r
631 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
634 ::wxLogError(_("Unable to get the file type!"));
\r
641 swInfo.fStoreDirectoryPathes = false;
\r
642 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
643 if (szDestDirBase == wxT("-----"))
\r
645 // 書庫ルートのときは書庫名にしておく。
\r
646 szDestDirBase = this->fnArchive.GetName();
\r
648 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
\r
649 if (! swInfo.fnDestinationDirectory.IsOk())
\r
651 ::wxLogError(_("Unable to make the temporary directory!"));
\r
657 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
663 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
664 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
665 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
666 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
668 // 必要なら書庫名でディレクトリを作成する。
\r
669 if (WillMakeDirByArcName(this, & mkDlg))
\r
671 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
672 if (! swInfo.fnDestinationDirectory.IsOk())
\r
674 ::wxLogError(_("Unable to make the destination directory!"));
\r
680 ProcessDialog procDlg;
\r
681 procDlg.Show(true);
\r
682 if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
684 this->ErrorCheck(tpi.nErrorCode);
\r
686 procDlg.Show(false);
\r
690 if (mkDlg.cbOpenAfter->IsChecked())
\r
694 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
698 if (mkDlg.cbExitAfter->IsChecked())
\r
706 wxArrayString asFiles;
\r
710 asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName());
\r
711 if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
\r
714 // Linuxでは引用符で囲む必要がある。
\r
715 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
\r
717 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
\r
724 wxFileDataObject objFile;
\r
725 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
727 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
731 objFile.AddFile(szFileName);
\r
733 asFiles.Add(szFileName);
\r
737 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
\r
741 wxDropSource dropSource(objFile, this);
\r
742 if (dropSource.DoDragDrop() != wxDragMove)
\r
745 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
751 // ファイルと一時ディレクトリを削除。
\r
752 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
754 ::wxRemoveFile(asFiles[i]);
\r
756 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
\r
760 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
762 // 全ファイル削除は危険ではないかと。
\r
763 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
768 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
774 TPI_SWITCHES swInfo;
\r
775 ProcessDialog procDlg;
\r
776 procDlg.Show(true);
\r
777 if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
779 this->ErrorCheck(tpi.nErrorCode);
\r
781 procDlg.Show(false);
\r
784 this->OnArcOpen(e);
\r
787 void MainFrame::OnArcTest(wxCommandEvent&)
\r
789 TPI_SWITCHES swInfo;
\r
790 ProcessDialog procDlg;
\r
791 procDlg.Show(true);
\r
792 bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));
\r
793 procDlg.Show(false);
\r
796 ::wxLogMessage(_("This is a correct archive."));
\r
800 this->ErrorCheck(tpi.nErrorCode);
\r
804 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
806 TPI_SWITCHES swInfo;
\r
807 ProcessDialog procDlg;
\r
808 procDlg.Show(true);
\r
809 if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
811 this->ErrorCheck(tpi.nErrorCode);
\r
813 procDlg.Show(false);
\r
816 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
819 this->menubar->Check(n, true);
\r
820 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
821 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
822 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
825 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
827 this->toolbar->Show(e.IsChecked());
\r
830 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
832 this->statusbar->Show(e.IsChecked());
\r
835 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
837 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
839 this->list_ctrl->Select(i, true);
\r
845 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
848 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
850 this->list_ctrl->showFileInfo.Clear();
\r
851 this->list_ctrl->DeleteAllItems();
\r
852 g_hIconLL.RemoveAll();
\r
853 g_hIconLS.RemoveAll();
\r
855 // 現在のアイテムの選択状態を無効にしておく。
\r
856 long nSelected = this->list_ctrl->GetFirstSelected();
\r
857 while (nSelected != -1)
\r
859 this->list_ctrl->Select(nSelected, false);
\r
860 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
864 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
865 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
867 // 配列と比較し、パスが一致しなければ消す。
\r
868 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
871 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
874 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
880 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
885 this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
\r
890 this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
\r
891 this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
\r
894 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
896 // TODO : アイテムが子階層を持っていても展開できない。
\r
897 this->tree_ctrl->SelectItem(e.GetItem());
\r
901 this->OnArcExtract(e1);
\r
906 void MainFrame::OnListItemDClick(wxListEvent&)
\r
910 this->OnArcExtract(e);
\r
913 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
915 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
917 // アイテムを選択せずドラッグしようとした場合。
\r
923 this->OnArcExtract(e);
\r
928 void MainFrame::OnFilter(wxCommandEvent&)
\r
931 e.SetItem(this->tree_ctrl->GetSelection());
\r
932 this->OnTreeChanged(e);
\r
937 wxULongLong_t MainFrame::LoadTPI(wxString szFileName)
\r
940 wxDir fs(L_DIR_B_LIB);
\r
941 wxULongLong_t llFileCount = 0;
\r
942 wxString szTPIName;
\r
943 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
948 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, 0))
\r
955 tpi.SetCallbackProc(TPICallbackProc);
\r
958 if (! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)
\r
966 while (fs.GetNext(& szTPIName));
\r
968 return llFileCount;
\r
971 int MainFrame::ErrorCheck(int nErrorCode)
\r
973 switch (nErrorCode)
\r
975 case TPI_ERROR_SUCCESS:
\r
976 case TPI_CALLBACK_CONTINUE:
\r
978 case TPI_ERROR_D_UNSUPPORTED:
\r
979 ::wxLogError(_("Sorry, this function is not supported yet."));
\r
981 case TPI_ERROR_D_SKIPPED:
\r
982 case TPI_CALLBACK_CANCEL:
\r
983 ::wxLogError(_("This operation is canceled by the user."));
\r
986 ::wxLogError(_("Error code: %d"), nErrorCode);
\r