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 this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);
\r
247 fd.GetFilenames(mkDlg.files);
\r
251 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
252 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
254 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
256 wxFileName fn(mkDlg.files[n]);
\r
257 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
258 mkDlg.files[n] = fn.GetFullPath();
\r
262 this->OnArcClose(e);
\r
263 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
264 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
265 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
266 this->fnArchive.SetEmptyExt();
\r
267 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
270 mkDlg.InitDialog();
\r
271 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
273 this->statusbar->SetStatusText(wxEmptyString, 4);
\r
276 this->statusbar->SetStatusText(wxEmptyString, 4);
\r
279 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
280 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
281 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
282 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
283 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
284 swInfo.sCompressLevel = mkDlg.scLevel->GetValue();
\r
285 swInfo.sRecoveryRecord = mkDlg.scRR->GetValue();
\r
286 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
287 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
288 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
291 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
\r
292 swInfo.llSplitSize = ll;
\r
296 int nSelected = mkDlg.chType->GetSelection();
\r
297 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
298 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
\r
300 ::wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));
\r
305 if (! tpi.SetCallbackProc(TPICallbackProc))
\r
307 ::wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));
\r
311 ProcessDialog procDlg;
\r
312 procDlg.InitDialog();
\r
313 procDlg.Show(true);
\r
314 if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
316 this->ErrorCheck(tpi.nErrorCode);
\r
319 procDlg.Show(false);
\r
322 if (mkDlg.cbOpenAfter->IsChecked())
\r
326 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
330 if (mkDlg.cbExitAfter->IsChecked())
\r
337 this->OnArcOpen(e);
\r
340 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
343 if (e.GetId() == XRCID("Arc_Open"))
\r
345 wxFileDialog fd(this);
\r
346 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
347 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
348 if (fd.ShowModal() == wxID_CANCEL)
\r
352 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
353 this->fnArchive = wxFileName(fd.GetPath());
\r
355 this->OnArcClose(e);
\r
358 ProcessDialog procDlg;
\r
359 procDlg.InitDialog();
\r
360 procDlg.Show(true);
\r
362 // TPIを読み込み、最初のコールバックを送信。
\r
363 TPI_PROCESSINFO piInfo;
\r
364 piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
365 piInfo.uStatus = 0x1000;
\r
366 piInfo.llProcessedSize = 0;
\r
367 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
368 piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
\r
369 if (piInfo.fiInfo.llUnpackedSize.ToULong() == 0)
\r
371 procDlg.Show(false);
\r
373 ::wxLogError(_("No plug-in supporting this archive was found!"));
\r
376 TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
379 tpi.SetCallbackProc(TPICallbackProc);
\r
382 this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
\r
385 if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
\r
387 procDlg.Show(false);
\r
389 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));
\r
394 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
395 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
396 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
398 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
399 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
400 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
401 this->tree_ctrl->SetImageList(& g_hIconT);
\r
403 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
405 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
407 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
409 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
412 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
414 piInfo.uStatus = 0x1001;
\r
417 piInfo.llProcessedSize++;
\r
418 if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
420 procDlg.Show(false);
\r
421 tpi.CloseArchive();
\r
423 this->OnArcClose(e);
\r
428 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
\r
430 // ディレクトリ属性を含むものについては除去。
\r
431 if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
438 if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
\r
440 piInfo.fiInfo.uDanger = TRUE;
\r
441 ::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
443 // 空白の連続による拡張子偽装を検査。
\r
444 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
446 piInfo.fiInfo.uDanger = TRUE;
\r
447 ::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:%s\n"), piInfo.fiInfo.szStoredName.c_str());
\r
450 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
452 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
454 piInfo.fiInfo.uDanger = TRUE;
\r
455 ::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"), piInfo.fiInfo.szStoredName.c_str());
\r
459 case 0x200f: c = 0x2027; break;
\r
460 case 0x202e: c = 0x2060; break;
\r
465 this->fileinfo.Add(piInfo.fiInfo);
\r
467 while (tpi.GetFileInformation(& piInfo.fiInfo, false));
\r
471 TPI_ARCHIVEINFO aiInfo;
\r
472 if (! tpi.GetArchiveInformation(& aiInfo))
\r
474 procDlg.Show(false);
\r
476 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));
\r
479 this->szComment = aiInfo.szComment;
\r
482 if (! tpi.CloseArchive())
\r
484 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));
\r
488 this->fileinfo.Shrink();
\r
489 this->tree_ctrl->ExpandAll();
\r
490 this->tree_ctrl->ScrollTo(idArchive);
\r
491 this->tree_ctrl->SelectItem(idArchive);
\r
492 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
495 this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
\r
496 this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);
\r
497 this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + _(" B -> ") + aiInfo.llPackedSize.ToString() + _(" B"), 2);
\r
498 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
\r
499 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
502 SetMenuToolState("Arc_Close", true);
\r
503 SetMenuToolState("Arc_Add", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && aiInfo.fiInfo.fArchive);
\r
504 SetMenuToolState("Arc_SFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && aiInfo.nSFXType == 0);
\r
505 SetMenuToolState("Arc_UnSFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
\r
506 SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
507 SetMenuToolState("Arc_Delete", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && aiInfo.fiInfo.fArchive);
\r
508 SetMenuToolState("Arc_Test", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
509 SetMenuToolState("Arc_Repair", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
511 procDlg.Show(false);
\r
514 void MainFrame::OnArcClose(wxCommandEvent&)
\r
516 // ツリービュー・リストビュー設定。
\r
517 this->tree_ctrl->DeleteAllItems();
\r
518 this->list_ctrl->DeleteAllItems();
\r
519 this->list_ctrl->showFileInfo.Clear();
\r
522 SetMenuToolState("Arc_Close", false);
\r
523 SetMenuToolState("Arc_Add", false);
\r
524 SetMenuToolState("Arc_SFX", false);
\r
525 SetMenuToolState("Arc_UnSFX", false);
\r
526 SetMenuToolState("Arc_Extract", false);
\r
527 SetMenuToolState("Arc_Delete", false);
\r
528 SetMenuToolState("Arc_Test", false);
\r
529 SetMenuToolState("Arc_Repair", false);
\r
531 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
533 this->statusbar->SetStatusText(wxEmptyString, i);
\r
535 this->fileinfo.Clear();
\r
536 this->szComment.Clear();
\r
538 g_hIconT.RemoveAll();
\r
539 g_hIconLL.RemoveAll();
\r
540 g_hIconLS.RemoveAll();
\r
541 this->tpi.FreeLibrary();
\r
544 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
547 wxArrayString files;
\r
548 wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));
\r
549 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
550 if (fd.ShowModal() == wxID_CANCEL)
\r
554 fd.GetFilenames(files);
\r
555 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
558 TPI_SWITCHES swInfo;
\r
559 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
560 swInfo.fMakeSFX = false;
\r
561 swInfo.pCustomSwitches = NULL;
\r
563 ProcessDialog procDlg;
\r
564 procDlg.InitDialog();
\r
565 procDlg.Show(true);
\r
566 if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))
\r
568 this->ErrorCheck(tpi.nErrorCode);
\r
570 procDlg.Show(false);
\r
573 this->OnArcOpen(e);
\r
576 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
578 TPI_SWITCHES swInfo;
\r
579 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
582 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
583 fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
584 if (fd.ShowModal() == wxID_CANCEL)
\r
588 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
589 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
591 wxArrayString files;
\r
592 files.Add(fd.GetPath());
\r
594 ProcessDialog procDlg;
\r
595 procDlg.InitDialog();
\r
596 procDlg.Show(true);
\r
597 if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
\r
599 this->ErrorCheck(tpi.nErrorCode);
\r
601 procDlg.Show(false);
\r
604 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
606 TPI_SWITCHES swInfo;
\r
607 swInfo.pCustomSwitches = NULL;
\r
609 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。
\r
610 int nMode = e.GetInt();
\r
612 wxFileType * ftFile = NULL;
\r
614 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
616 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
617 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
618 mkDlg.bIsMake = false;
\r
619 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
626 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
\r
629 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。
\r
630 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
633 ::wxLogError(_("Unable to get the file type!"));
\r
640 swInfo.fStoreDirectoryPathes = false;
\r
641 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
642 if (szDestDirBase == wxT("-----"))
\r
644 // 書庫ルートのときは書庫名にしておく。
\r
645 szDestDirBase = this->fnArchive.GetName();
\r
647 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
\r
648 if (! swInfo.fnDestinationDirectory.IsOk())
\r
650 ::wxLogError(_("Unable to make the temporary directory!"));
\r
656 mkDlg.InitDialog();
\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.InitDialog();
\r
682 procDlg.Show(true);
\r
683 if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
685 this->ErrorCheck(tpi.nErrorCode);
\r
687 procDlg.Show(false);
\r
691 if (mkDlg.cbOpenAfter->IsChecked())
\r
695 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
699 if (mkDlg.cbExitAfter->IsChecked())
\r
707 wxArrayString asFiles;
\r
711 asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
\r
712 if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
\r
715 // Linuxでは引用符で囲む必要がある。
\r
716 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
\r
718 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
\r
725 wxFileDataObject objFile;
\r
726 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
728 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
\r
732 objFile.AddFile(szFileName);
\r
734 asFiles.Add(szFileName);
\r
738 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
\r
742 wxDropSource dropSource(objFile, this);
\r
743 if (dropSource.DoDragDrop() != wxDragMove)
\r
746 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
752 // ファイルと一時ディレクトリを削除。
\r
753 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
755 ::wxRemoveFile(asFiles[i]);
\r
757 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
\r
761 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
763 // 全ファイル削除は危険ではないかと。
\r
764 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
769 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
775 TPI_SWITCHES swInfo;
\r
776 ProcessDialog procDlg;
\r
777 procDlg.InitDialog();
\r
778 procDlg.Show(true);
\r
779 if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
781 this->ErrorCheck(tpi.nErrorCode);
\r
783 procDlg.Show(false);
\r
786 this->OnArcOpen(e);
\r
789 void MainFrame::OnArcTest(wxCommandEvent&)
\r
791 TPI_SWITCHES swInfo;
\r
792 ProcessDialog procDlg;
\r
793 procDlg.InitDialog();
\r
794 procDlg.Show(true);
\r
795 bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));
\r
796 procDlg.Show(false);
\r
799 ::wxLogMessage(_("This is a correct archive."));
\r
803 this->ErrorCheck(tpi.nErrorCode);
\r
807 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
809 TPI_SWITCHES swInfo;
\r
810 ProcessDialog procDlg;
\r
811 procDlg.InitDialog();
\r
812 procDlg.Show(true);
\r
813 if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
815 this->ErrorCheck(tpi.nErrorCode);
\r
817 procDlg.Show(false);
\r
820 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
823 this->menubar->Check(n, true);
\r
824 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
825 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
826 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
829 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
831 this->toolbar->Show(e.IsChecked());
\r
834 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
836 this->statusbar->Show(e.IsChecked());
\r
839 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
841 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
843 this->list_ctrl->Select(i, true);
\r
849 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
852 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
854 this->list_ctrl->showFileInfo.Clear();
\r
855 this->list_ctrl->DeleteAllItems();
\r
856 g_hIconLL.RemoveAll();
\r
857 g_hIconLS.RemoveAll();
\r
859 // 現在のアイテムの選択状態を無効にしておく。
\r
860 long nSelected = this->list_ctrl->GetFirstSelected();
\r
861 while (nSelected != -1)
\r
863 this->list_ctrl->Select(nSelected, false);
\r
864 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
868 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
869 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
871 // 配列と比較し、パスが一致しなければ消す。
\r
872 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
875 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
878 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
884 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
889 this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
\r
894 this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
\r
895 this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
\r
898 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
900 // TODO : アイテムが子階層を持っていても展開できない。
\r
901 this->tree_ctrl->SelectItem(e.GetItem());
\r
905 this->OnArcExtract(e1);
\r
910 void MainFrame::OnListItemDClick(wxListEvent&)
\r
914 this->OnArcExtract(e);
\r
917 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
919 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
921 // アイテムを選択せずドラッグしようとした場合。
\r
927 this->OnArcExtract(e);
\r
932 void MainFrame::OnFilter(wxCommandEvent&)
\r
935 e.SetItem(this->tree_ctrl->GetSelection());
\r
936 this->OnTreeChanged(e);
\r
941 wxULongLong MainFrame::LoadTPI(wxString szFileName)
\r
945 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
946 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
947 wxULongLong llFileCount = 0;
\r
948 while (! szTPIName.IsEmpty())
\r
951 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)
\r
954 szTPIName = fs.FindNext();
\r
959 return llFileCount;
\r
962 int MainFrame::ErrorCheck(int nErrorCode)
\r
964 switch (nErrorCode)
\r
966 case TPI_ERROR_SUCCESS:
\r
967 case TPI_CALLBACK_CONTINUE:
\r
969 case TPI_ERROR_D_UNSUPPORTED:
\r
970 ::wxLogError(_("Sorry, this function is not supported yet."));
\r
972 case TPI_ERROR_D_SKIPPED:
\r
973 case TPI_CALLBACK_CANCEL:
\r
974 ::wxLogError(_("This operation is canceled by the user."));
\r
977 ::wxLogError(_("Error code: %d"), nErrorCode);
\r