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, (long) a);
\r
63 this->conf.WriteId(CONF_WINDOW_HEIGHT,(long) b);
\r
64 this->GetPosition(& a, & b);
\r
65 this->conf.WriteId(CONF_WINDOW_X, (long) a);
\r
66 this->conf.WriteId(CONF_WINDOW_Y, (long) b);
\r
68 this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, (long) 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, (long) (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,(long) this->list_ctrl->GetColumnWidth(0));
\r
79 this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED,(long) this->list_ctrl->GetColumnWidth(1));
\r
80 this->conf.WriteId(CONF_LISTVIEW_C_PACKED, (long) this->list_ctrl->GetColumnWidth(2));
\r
81 this->conf.WriteId(CONF_LISTVIEW_C_RATIO, (long) this->list_ctrl->GetColumnWidth(3));
\r
82 this->conf.WriteId(CONF_LISTVIEW_C_METHOD, (long) this->list_ctrl->GetColumnWidth(4));
\r
83 this->conf.WriteId(CONF_LISTVIEW_C_ATTR, (long) this->list_ctrl->GetColumnWidth(5));
\r
84 this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD, (long) this->list_ctrl->GetColumnWidth(6));
\r
85 this->conf.WriteId(CONF_LISTVIEW_C_PATH, (long) this->list_ctrl->GetColumnWidth(7));
\r
86 this->conf.WriteId(CONF_LISTVIEW_C_TYPE, (long) this->list_ctrl->GetColumnWidth(8));
\r
87 this->conf.WriteId(CONF_LISTVIEW_C_NO, (long) this->list_ctrl->GetColumnWidth(9));
\r
88 this->conf.WriteId(CONF_LISTVIEW_S_COLUMN, (long) 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));
\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
192 this->cmdLine.SetSwitchChars(wxT("-"));
\r
193 this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, _("(command) Extract filenames in archive."));
\r
194 this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, _("(command) List archive(default)."));
\r
195 this->cmdLine.AddParam(_("archive"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
\r
196 this->cmdLine.AddParam(_("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
\r
197 if (this->cmdLine.Parse() == 0)
\r
199 if (this->cmdLine.GetParamCount() == 0)
\r
205 this->fnArchive = wxFileName(this->cmdLine.GetParam(0));
\r
206 this->fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);
\r
207 this->OnArcOpen(e);
\r
208 if (this->cmdLine.Found(wxT("x")))
\r
211 this->OnArcExtract(e);
\r
219 void MainFrame::OnExit(wxCommandEvent&)
\r
224 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
226 TPI_SWITCHES swInfo;
\r
227 swInfo.pCustomSwitches = NULL;
\r
231 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
232 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
234 if (e.GetClientData() == NULL)
\r
237 wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
238 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
239 if (fd.ShowModal() == wxID_CANCEL)
\r
243 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
244 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
245 fd.GetFilenames(mkDlg.files);
\r
249 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
250 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
252 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
254 wxFileName fn(mkDlg.files[n]);
\r
255 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
256 mkDlg.files[n] = fn.GetFullPath();
\r
260 this->OnArcClose(e);
\r
261 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
262 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
263 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
264 this->fnArchive.SetEmptyExt();
\r
265 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
268 mkDlg.InitDialog();
\r
269 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
275 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
276 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
277 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
278 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
279 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
280 swInfo.sCompressLevel = mkDlg.scLevel->GetValue();
\r
281 swInfo.sRecoveryRecord = mkDlg.scRR->GetValue();
\r
282 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
283 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
284 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
287 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
\r
288 swInfo.llSplitSize = ll;
\r
292 int nSelected = mkDlg.chType->GetSelection();
\r
293 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
294 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
\r
296 ::wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));
\r
301 if (! tpi.SetCallbackProc(TPICallbackProc))
\r
303 ::wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));
\r
307 ProcessDialog procDlg;
\r
308 procDlg.InitDialog();
\r
309 procDlg.Show(true);
\r
310 if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
312 this->ErrorCheck(tpi.nErrorCode);
\r
315 procDlg.Show(false);
\r
318 if (mkDlg.cbOpenAfter->IsChecked())
\r
322 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
326 if (mkDlg.cbExitAfter->IsChecked())
\r
333 this->OnArcOpen(e);
\r
336 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
339 if (e.GetId() == XRCID("Arc_Open"))
\r
341 wxFileDialog fd(this);
\r
342 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
343 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
344 if (fd.ShowModal() == wxID_CANCEL)
\r
348 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
349 this->fnArchive = wxFileName(fd.GetPath());
\r
351 this->OnArcClose(e);
\r
354 ProcessDialog procDlg;
\r
355 procDlg.InitDialog();
\r
356 procDlg.Show(true);
\r
358 // TPIを読み込み、最初のコールバックを送信。
\r
359 TPI_PROCESSINFO piInfo;
\r
360 piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
361 piInfo.uStatus = 0x1000;
\r
362 piInfo.llProcessedSize = 0;
\r
363 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
364 piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
\r
365 if (piInfo.fiInfo.llUnpackedSize.ToULong() == 0)
\r
367 procDlg.Show(false);
\r
369 ::wxLogError(_("No plug-in supporting this archive was found!"));
\r
372 TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
375 tpi.SetCallbackProc(TPICallbackProc);
\r
378 this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
\r
381 if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
\r
383 procDlg.Show(false);
\r
385 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));
\r
390 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
391 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
392 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
394 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
395 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
396 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
397 this->tree_ctrl->SetImageList(& g_hIconT);
\r
399 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
401 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
403 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
405 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
408 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
410 piInfo.uStatus = 0x1001;
\r
413 piInfo.llProcessedSize++;
\r
414 if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
416 procDlg.Show(false);
\r
417 tpi.CloseArchive();
\r
419 this->OnArcClose(e);
\r
424 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
\r
426 // ディレクトリ属性を含むものについては除去。
\r
427 if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
434 if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
\r
436 piInfo.fiInfo.uDanger = TRUE;
\r
437 ::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.szStoredName.c_str());
\r
439 // 空白の連続による拡張子偽装を検査。
\r
440 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
442 piInfo.fiInfo.uDanger = TRUE;
\r
443 ::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.szStoredName.c_str());
\r
446 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
448 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
450 piInfo.fiInfo.uDanger = TRUE;
\r
451 ::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.szStoredName.c_str());
\r
455 case 0x200f: c = 0x2027; break;
\r
456 case 0x202e: c = 0x2060; break;
\r
461 this->fileinfo.Add(piInfo.fiInfo);
\r
463 while (tpi.GetFileInformation(& piInfo.fiInfo, false));
\r
466 // GetFileInformationがエラー終了した場合。
\r
467 if (tpi.nErrorCode != TPI_ERROR_S_ENDOFDATA)
\r
469 ::wxLogError(_("Error: %s!"), wxT("GetFileInformation()"));
\r
473 if (! tpi.GetArchiveInformation(& this->aiArchive))
\r
475 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));
\r
479 if (! tpi.CloseArchive())
\r
481 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));
\r
485 this->fileinfo.Shrink();
\r
486 this->tree_ctrl->ExpandAll();
\r
487 this->tree_ctrl->ScrollTo(idArchive);
\r
488 this->tree_ctrl->SelectItem(idArchive);
\r
489 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
490 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
493 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
494 this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);
\r
495 this->statusbar->SetStatusText(this->aiArchive.llUnpackedSize.ToString() + _(" B -> ") + this->aiArchive.llPackedSize.ToString() + _(" B"), 2);
\r
496 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
497 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
500 SetMenuToolState("Arc_Close", true);
\r
501 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
502 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && this->aiArchive.nSFXType == 0);
\r
503 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.nSFXType != 0);
\r
504 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
505 SetMenuToolState("Arc_Delete", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
506 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
507 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
509 procDlg.Show(false);
\r
512 void MainFrame::OnArcClose(wxCommandEvent&)
\r
514 // ツリービュー・リストビュー設定。
\r
515 this->tree_ctrl->DeleteAllItems();
\r
516 this->list_ctrl->DeleteAllItems();
\r
517 this->list_ctrl->showFileInfo.Clear();
\r
520 SetMenuToolState("Arc_Close", false);
\r
521 SetMenuToolState("Arc_Add", false);
\r
522 SetMenuToolState("Arc_SFX", false);
\r
523 SetMenuToolState("Arc_UnSFX", false);
\r
524 SetMenuToolState("Arc_Extract", false);
\r
525 SetMenuToolState("Arc_Delete", false);
\r
526 SetMenuToolState("Arc_Test", false);
\r
527 SetMenuToolState("Arc_Repair", false);
\r
529 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
531 this->statusbar->SetStatusText(wxEmptyString, i);
\r
533 this->fileinfo.Clear();
\r
534 this->aiArchive.szComment.Clear();
\r
535 this->aiArchive.fnArchive.Clear();
\r
536 this->aiArchive.fiInfo.szTypeName.Clear();
\r
537 this->aiArchive.fiInfo.szSuffix.Clear();
\r
538 this->aiArchive.fiInfo.szEngineName.Clear();
\r
539 this->aiArchive.fiInfo.szTPIName.Clear();
\r
541 g_hIconT.RemoveAll();
\r
542 g_hIconLL.RemoveAll();
\r
543 g_hIconLS.RemoveAll();
\r
544 this->tpi.FreeLibrary();
\r
547 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
551 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
552 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
553 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
556 wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
557 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
558 if (fd.ShowModal() == wxID_CANCEL)
\r
562 fd.GetFilenames(mkDlg.files);
\r
563 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
566 mkDlg.InitDialog();
\r
567 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
573 TPI_SWITCHES swInfo;
\r
574 swInfo.pCustomSwitches = NULL;
\r
575 swInfo.fMakeSFX = false;
\r
576 swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());
\r
577 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
578 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
579 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
580 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
581 swInfo.sCompressLevel = mkDlg.scLevel->GetValue();
\r
582 swInfo.sRecoveryRecord = mkDlg.scRR->GetValue();
\r
583 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
584 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
585 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
587 ProcessDialog procDlg;
\r
588 procDlg.InitDialog();
\r
589 procDlg.Show(true);
\r
590 if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
592 this->ErrorCheck(tpi.nErrorCode);
\r
594 procDlg.Show(false);
\r
596 if (mkDlg.cbOpenAfter->IsChecked())
\r
600 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
604 if (mkDlg.cbExitAfter->IsChecked())
\r
610 // 終了しない場合は書庫を再読み込み。
\r
611 this->OnArcOpen(e);
\r
614 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
616 TPI_SWITCHES swInfo;
\r
617 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
620 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
621 fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
622 if (fd.ShowModal() == wxID_CANCEL)
\r
626 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
627 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
629 wxArrayString files;
\r
630 files.Add(fd.GetPath());
\r
632 ProcessDialog procDlg;
\r
633 procDlg.InitDialog();
\r
634 procDlg.Show(true);
\r
635 if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
\r
637 this->ErrorCheck(tpi.nErrorCode);
\r
639 procDlg.Show(false);
\r
642 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
644 TPI_SWITCHES swInfo;
\r
645 swInfo.pCustomSwitches = NULL;
\r
647 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。
\r
648 int nMode = e.GetInt();
\r
650 wxFileType * ftFile = NULL;
\r
652 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
654 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
655 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
656 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
657 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
664 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
\r
667 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。
\r
668 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
671 ::wxLogError(_("Unable to get the file type!"));
\r
678 swInfo.fStoreDirectoryPathes = false;
\r
679 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
680 if (szDestDirBase == wxT("-----"))
\r
682 // 書庫ルートのときは書庫名にしておく。
\r
683 szDestDirBase = this->fnArchive.GetName();
\r
685 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
\r
686 if (! swInfo.fnDestinationDirectory.IsOk())
\r
688 ::wxLogError(_("Unable to make the temporary directory!"));
\r
694 mkDlg.InitDialog();
\r
695 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
701 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
702 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
703 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
704 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
706 // 必要なら書庫名でディレクトリを作成する。
\r
707 if (WillMakeDirByArcName(this, & mkDlg))
\r
709 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
710 if (! swInfo.fnDestinationDirectory.IsOk())
\r
712 ::wxLogError(_("Unable to make the destination directory!"));
\r
718 ProcessDialog procDlg;
\r
719 procDlg.InitDialog();
\r
720 procDlg.Show(true);
\r
721 if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
723 this->ErrorCheck(tpi.nErrorCode);
\r
725 procDlg.Show(false);
\r
729 if (mkDlg.cbOpenAfter->IsChecked())
\r
733 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
737 if (mkDlg.cbExitAfter->IsChecked())
\r
745 wxArrayString asFiles;
\r
749 asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
\r
750 if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
\r
753 // Linuxでは引用符で囲む必要がある。
\r
754 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
\r
756 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
\r
763 wxFileDataObject objFile;
\r
764 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
766 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
\r
770 objFile.AddFile(szFileName);
\r
772 asFiles.Add(szFileName);
\r
776 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
\r
780 wxDropSource dropSource(objFile, this);
\r
781 if (dropSource.DoDragDrop() != wxDragMove)
\r
784 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
790 // ファイルと一時ディレクトリを削除。
\r
791 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
793 ::wxRemoveFile(asFiles[i]);
\r
795 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
\r
799 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
801 // 全ファイル削除は危険ではないかと。
\r
802 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
807 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
813 TPI_SWITCHES swInfo;
\r
814 ProcessDialog procDlg;
\r
815 procDlg.InitDialog();
\r
816 procDlg.Show(true);
\r
817 if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
819 this->ErrorCheck(tpi.nErrorCode);
\r
821 procDlg.Show(false);
\r
824 this->OnArcOpen(e);
\r
827 void MainFrame::OnArcTest(wxCommandEvent&)
\r
829 TPI_SWITCHES swInfo;
\r
830 ProcessDialog procDlg;
\r
831 procDlg.InitDialog();
\r
832 procDlg.Show(true);
\r
833 bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));
\r
834 procDlg.Show(false);
\r
837 ::wxLogMessage(_("This is a correct archive."));
\r
841 this->ErrorCheck(tpi.nErrorCode);
\r
845 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
847 TPI_SWITCHES swInfo;
\r
848 ProcessDialog procDlg;
\r
849 procDlg.InitDialog();
\r
850 procDlg.Show(true);
\r
851 if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
853 this->ErrorCheck(tpi.nErrorCode);
\r
855 procDlg.Show(false);
\r
858 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
861 this->menubar->Check(n, true);
\r
862 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
863 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
864 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
867 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
869 this->toolbar->Show(e.IsChecked());
\r
872 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
874 this->statusbar->Show(e.IsChecked());
\r
877 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
879 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
881 this->list_ctrl->Select(i, true);
\r
887 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
890 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
892 this->list_ctrl->showFileInfo.Clear();
\r
893 this->list_ctrl->DeleteAllItems();
\r
894 g_hIconLL.RemoveAll();
\r
895 g_hIconLS.RemoveAll();
\r
897 // 現在のアイテムの選択状態を無効にしておく。
\r
898 long nSelected = this->list_ctrl->GetFirstSelected();
\r
899 while (nSelected != -1)
\r
901 this->list_ctrl->Select(nSelected, false);
\r
902 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
906 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
907 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
909 // 配列と比較し、パスが一致しなければ消す。
\r
910 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
913 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
916 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
922 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
927 this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
\r
932 this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
\r
933 this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
\r
936 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
938 // TODO : アイテムが子階層を持っていても展開できない。
\r
939 this->tree_ctrl->SelectItem(e.GetItem());
\r
943 this->OnArcExtract(e1);
\r
948 void MainFrame::OnListItemDClick(wxListEvent&)
\r
952 this->OnArcExtract(e);
\r
955 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
957 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
959 // アイテムを選択せずドラッグしようとした場合。
\r
965 this->OnArcExtract(e);
\r
970 void MainFrame::OnFilter(wxCommandEvent&)
\r
973 e.SetItem(this->tree_ctrl->GetSelection());
\r
974 this->OnTreeChanged(e);
\r
979 wxULongLong MainFrame::LoadTPI(wxString szFileName)
\r
983 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
984 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
985 wxULongLong llFileCount = 0;
\r
986 while (! szTPIName.IsEmpty())
\r
989 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)
\r
992 szTPIName = fs.FindNext();
\r
997 return llFileCount;
\r
1000 int MainFrame::ErrorCheck(int nErrorCode)
\r
1002 switch (nErrorCode)
\r
1004 case TPI_ERROR_SUCCESS:
\r
1005 case TPI_CALLBACK_CONTINUE:
\r
1007 case TPI_ERROR_D_UNSUPPORTED:
\r
1008 ::wxLogError(_("Sorry, this function is not supported yet."));
\r
1010 case TPI_ERROR_D_SKIPPED:
\r
1011 case TPI_CALLBACK_CANCEL:
\r
1012 ::wxLogError(_("This operation is canceled by the user."));
\r
1015 ::wxLogError(_("Error code: %d"), nErrorCode);
\r
1017 return nErrorCode;
\r