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(), conf(wxEmptyString, wxEmptyString, L_DIR_BIN wxT("lychee.conf"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH)
\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.Write(wxT("Window-Width"), a);
\r
63 this->conf.Write(wxT("Window-Height"), b);
\r
64 this->GetPosition(& a, & b);
\r
65 this->conf.Write(wxT("Window-X"), a);
\r
66 this->conf.Write(wxT("Window-Y"), b);
\r
68 this->conf.Write(wxT("Splitter-Pos"), this->window_splitter->GetSashPosition());
\r
71 this->conf.Write(wxT("StatusBar-Show"), this->statusbar->IsShown());
\r
72 this->conf.Write(wxT("ToolBar-Show"), this->toolbar->IsShown());
\r
75 this->conf.Write(wxT("ListView-IconMode"), 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.Write(wxT("ListView-C-Filename"), this->list_ctrl->GetColumnWidth(0));
\r
79 this->conf.Write(wxT("ListView-C-Unpacked"), this->list_ctrl->GetColumnWidth(1));
\r
80 this->conf.Write(wxT("ListView-C-Packed"), this->list_ctrl->GetColumnWidth(2));
\r
81 this->conf.Write(wxT("ListView-C-Ratio"), this->list_ctrl->GetColumnWidth(3));
\r
82 this->conf.Write(wxT("ListView-C-Method"), this->list_ctrl->GetColumnWidth(4));
\r
83 this->conf.Write(wxT("ListView-C-Attr"), this->list_ctrl->GetColumnWidth(5));
\r
84 this->conf.Write(wxT("ListView-C-Lastmodified"), this->list_ctrl->GetColumnWidth(6));
\r
85 this->conf.Write(wxT("ListView-C-Path"), this->list_ctrl->GetColumnWidth(7));
\r
86 this->conf.Write(wxT("ListView-C-Type"), this->list_ctrl->GetColumnWidth(8));
\r
87 this->conf.Write(wxT("ListView-C-No"), this->list_ctrl->GetColumnWidth(9));
\r
88 this->conf.Write(wxT("ListView-SortColumn"), g_nSortColumn);
\r
89 this->conf.Write(wxT("ListView-SortAscend"), 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.Read(wxT("Window-X"), 0l), this->conf.Read(wxT("Window-Y"), 0l), this->conf.Read(wxT("Window-Width"), 800), this->conf.Read(wxT("Window-Height"), 400));
\r
146 wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
\r
152 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
\r
153 this->SetIcon(icon);
\r
156 this->OnArcClose(e);
\r
159 this->window_splitter->SetSashPosition(this->conf.Read(wxT("Splitter-Pos"), 200));
\r
162 int nIconMode = this->conf.Read(wxT("ListView-IconMode"), 0l);
\r
163 e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
\r
164 this->OnViewMode(e);
\r
165 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
166 this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
\r
167 this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Filename"), 140));
\r
168 this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Unpacked"), 80));
\r
169 this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Packed"), 80));
\r
170 this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Ratio"), 50));
\r
171 this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Method"), 60));
\r
172 this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Attr"), 50));
\r
173 this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Lastmodified"), 150));
\r
174 this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Path"), 100));
\r
175 this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Type"), 100));
\r
176 this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-No"), 35));
\r
177 g_nSortColumn = this->conf.Read(wxT("ListView-SortColumn"), 9);
\r
178 g_fSortAscend = this->conf.Read(wxT("ListView-SortAscend"), 1) == 1;
\r
179 this->list_ctrl->SetDropTarget(new myFileDropTarget(this));
\r
181 // ツールバー/ステータスバー設定。
\r
182 int nStatusBarParts[] = {70, 70, 180, 50, -1};
\r
183 this->statusbar->SetFieldsCount(5, nStatusBarParts);
\r
184 this->SetStatusBarPane(-1);
\r
185 bool fShow = this->conf.Read(wxT("StatusBar-Show"), 1) == 1;
\r
186 this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
\r
187 this->statusbar->Show(fShow);
\r
188 fShow = this->conf.Read(wxT("ToolBar-Show"), 1) == 1;
\r
189 this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
\r
190 this->toolbar->Show(fShow);
\r
193 this->cmdLine.SetSwitchChars(wxT("-"));
\r
194 this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, _("(command) Extract filenames in archive."));
\r
195 this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, _("(command) List archive(default)."));
\r
196 this->cmdLine.AddParam(_("archive"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
\r
197 this->cmdLine.AddParam(_("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
\r
198 if (this->cmdLine.Parse() == 0)
\r
200 if (this->cmdLine.GetParamCount() == 0)
\r
206 this->fnArchive = wxFileName(this->cmdLine.GetParam(0));
\r
207 this->fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);
\r
208 this->OnArcOpen(e);
\r
209 if (this->cmdLine.Found(wxT("x")))
\r
212 this->OnArcExtract(e);
\r
220 void MainFrame::OnExit(wxCommandEvent&)
\r
225 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
227 TPI_SWITCHES swInfo;
\r
228 swInfo.pCustomSwitches = NULL;
\r
232 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
233 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
235 if (e.GetClientData() == NULL)
\r
238 wxFileDialog fd(this, _("Choose files to compress"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
\r
239 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
240 if (fd.ShowModal() == wxID_CANCEL)
\r
244 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
245 this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
\r
246 this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);
\r
248 fd.GetFilenames(mkDlg.files);
\r
252 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
253 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
255 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
257 wxFileName fn(mkDlg.files[n]);
\r
258 bool fIsDir = fn.DirExists() && ! fn.FileExists();
\r
259 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
260 mkDlg.files[n] = fn.GetFullPath();
\r
263 mkDlg.files[n] += fn.GetPathSeparator();
\r
268 this->OnArcClose(e);
\r
269 mkDlg.InitDialog();
\r
270 mkDlg.cbDir->SetValue(swInfo.fnDestinationDirectory.GetPath());
\r
271 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
272 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
273 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
274 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
275 mkDlg.cbFileName->SetValue(this->fnArchive.GetName());
\r
278 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
280 this->statusbar->SetStatusText(wxEmptyString, 4);
\r
283 this->statusbar->SetStatusText(wxEmptyString, 4);
\r
286 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
287 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
288 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
289 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
290 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
291 swInfo.sCompressLevel = mkDlg.scLevel->GetValue();
\r
292 swInfo.sRecoveryRecord = mkDlg.scRR->GetValue();
\r
293 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
294 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
295 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
298 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
\r
299 swInfo.llSplitSize = ll;
\r
303 int nSelected = mkDlg.chType->GetSelection();
\r
304 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue(), swInfo.fMakeSFX ? EXE_EXT : mkDlg.afInfo[nSelected].szSuffix.BeforeFirst(wxT(';')));
\r
305 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
\r
307 ::ErrDlg(wxT("Error: InitLibrary()!"), this);
\r
312 if (! tpi.SetCallbackProc(TPICallbackProc))
\r
314 ::ErrDlg(wxT("Error: SetCallbackProc()!"), this);
\r
318 ProcessDialog procDlg;
\r
319 procDlg.InitDialog();
\r
320 procDlg.Show(true);
\r
321 if (! tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
323 this->ErrorCheck(tpi.nErrorCode);
\r
326 procDlg.Show(false);
\r
329 if (mkDlg.cbOpenAfter->IsChecked())
\r
333 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
337 if (mkDlg.cbExitAfter->IsChecked())
\r
344 this->OnArcOpen(e);
\r
347 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
350 if (e.GetId() == XRCID("Arc_Open"))
\r
352 wxFileDialog fd(this);
\r
353 fd.SetDirectory(this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
\r
354 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
355 if (fd.ShowModal() == wxID_CANCEL)
\r
359 this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
\r
360 this->fnArchive = wxFileName(fd.GetPath());
\r
362 this->OnArcClose(e);
\r
365 ProcessDialog procDlg;
\r
366 procDlg.InitDialog();
\r
367 procDlg.Show(true);
\r
369 // TPIを読み込み、最初のコールバックを送信。
\r
370 TPI_PROCESSINFO piInfo;
\r
371 piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
372 piInfo.uStatus = 0x1000;
\r
373 piInfo.llProcessedSize = 0;
\r
374 piInfo.fiInfo.fnFileName = this->fnArchive;
\r
375 piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
\r
376 if (piInfo.fiInfo.llUnpackedSize.ToULong() == 0)
\r
378 procDlg.Show(false);
\r
380 ::ErrDlg(_("No plug-in supporting this archive was found!"), this);
\r
383 TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
\r
386 tpi.SetCallbackProc(TPICallbackProc);
\r
389 this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
\r
392 if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
\r
394 procDlg.Show(false);
\r
396 ::ErrDlg(wxT("Error: OpenArchive()!"), this);
\r
400 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
401 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
402 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
403 this->tree_ctrl->SetImageList(& g_hIconT);
\r
405 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
407 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
409 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
411 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
414 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
416 piInfo.uStatus = 0x1001;
\r
419 piInfo.llProcessedSize++;
\r
420 if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
\r
422 procDlg.Show(false);
\r
423 tpi.CloseArchive();
\r
425 this->OnArcClose(e);
\r
430 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
\r
432 // ディレクトリ属性を含むものについては除去。
\r
433 if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
440 if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
\r
442 piInfo.fiInfo.uDanger = TRUE;
\r
443 ::WrnDlg(_("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") + piInfo.fiInfo.szStoredName, this);
\r
445 // 空白の連続による拡張子偽装を検査。
\r
446 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
448 piInfo.fiInfo.uDanger = TRUE;
\r
449 ::WrnDlg(_("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") + piInfo.fiInfo.szStoredName, this);
\r
452 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
454 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
456 piInfo.fiInfo.uDanger = TRUE;
\r
457 ::WrnDlg(_("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, this);
\r
461 case 0x200f: c = 0x2027; break;
\r
462 case 0x202e: c = 0x2060; break;
\r
467 this->fileinfo.Add(piInfo.fiInfo);
\r
469 while (tpi.GetFileInformation(& piInfo.fiInfo, false));
\r
473 TPI_ARCHIVEINFO aiInfo;
\r
474 if (! tpi.GetArchiveInformation(& aiInfo))
\r
476 procDlg.Show(false);
\r
478 ::ErrDlg(wxT("Error: GetArchiveInformation()!"), this);
\r
481 this->szComment = aiInfo.szComment;
\r
484 if (! tpi.CloseArchive())
\r
486 ::ErrDlg(wxT("Error: CloseArchive()!"), this);
\r
490 this->fileinfo.Shrink();
\r
491 this->tree_ctrl->ExpandAll();
\r
492 this->tree_ctrl->ScrollTo(idArchive);
\r
493 this->tree_ctrl->SelectItem(idArchive);
\r
494 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
497 this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
\r
498 this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);
\r
499 this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + _(" B -> ") + aiInfo.llPackedSize.ToString() + _(" B"), 2);
\r
500 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
\r
501 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
504 SetMenuToolState("Arc_Close", true);
\r
505 SetMenuToolState("Arc_Add", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && aiInfo.fiInfo.fArchive);
\r
506 SetMenuToolState("Arc_SFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && aiInfo.nSFXType == 0);
\r
507 SetMenuToolState("Arc_UnSFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
\r
508 SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
509 SetMenuToolState("Arc_Delete", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && aiInfo.fiInfo.fArchive);
\r
510 SetMenuToolState("Arc_Test", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
511 SetMenuToolState("Arc_Repair", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
513 procDlg.Show(false);
\r
516 void MainFrame::OnArcClose(wxCommandEvent&)
\r
518 // ツリービュー・リストビュー設定。
\r
519 this->tree_ctrl->DeleteAllItems();
\r
520 this->list_ctrl->DeleteAllItems();
\r
521 this->list_ctrl->showFileInfo.Clear();
\r
524 SetMenuToolState("Arc_Close", false);
\r
525 SetMenuToolState("Arc_Add", false);
\r
526 SetMenuToolState("Arc_SFX", false);
\r
527 SetMenuToolState("Arc_UnSFX", false);
\r
528 SetMenuToolState("Arc_Extract", false);
\r
529 SetMenuToolState("Arc_Delete", false);
\r
530 SetMenuToolState("Arc_Test", false);
\r
531 SetMenuToolState("Arc_Repair", false);
\r
533 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
535 this->statusbar->SetStatusText(wxEmptyString, i);
\r
537 this->fileinfo.Clear();
\r
538 this->szComment.Clear();
\r
540 g_hIconT.RemoveAll();
\r
541 g_hIconLL.RemoveAll();
\r
542 g_hIconLS.RemoveAll();
\r
543 this->tpi.FreeLibrary();
\r
546 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
549 wxArrayString files;
\r
550 wxFileDialog fd(this, _("Choose files to add"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
\r
551 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
552 if (fd.ShowModal() == wxID_CANCEL)
\r
556 fd.GetFilenames(files);
\r
557 this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
\r
560 TPI_SWITCHES swInfo;
\r
561 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
562 swInfo.fMakeSFX = false;
\r
563 swInfo.pCustomSwitches = NULL;
\r
565 ProcessDialog procDlg;
\r
566 procDlg.InitDialog();
\r
567 procDlg.Show(true);
\r
568 if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))
\r
570 this->ErrorCheck(tpi.nErrorCode);
\r
572 procDlg.Show(false);
\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.Write(wxT("LastOpenPath"), fd.GetDirectory());
\r
593 wxArrayString files;
\r
594 files.Add(fd.GetPath());
\r
596 ProcessDialog procDlg;
\r
597 procDlg.InitDialog();
\r
598 procDlg.Show(true);
\r
599 if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
\r
601 this->ErrorCheck(tpi.nErrorCode);
\r
603 procDlg.Show(false);
\r
606 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
608 TPI_SWITCHES swInfo;
\r
609 swInfo.pCustomSwitches = NULL;
\r
611 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。
\r
612 int nMode = e.GetInt();
\r
614 wxFileType * ftFile = NULL;
\r
616 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
618 ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
619 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
\r
620 mkDlg.bIsMake = false;
\r
621 mkDlg.files = MakeTargetFileList(this, nMode == 1);
\r
628 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
\r
631 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。
\r
632 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.Read(wxT("DefaultExt"), wxT("txt")));
\r
635 ::ErrDlg(_("Unable to get the file type!"), this);
\r
642 swInfo.fStoreDirectoryPathes = false;
\r
643 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
644 if (szDestDirBase == wxT("-----"))
\r
646 // 書庫ルートのときは書庫名にしておく。
\r
647 szDestDirBase = this->fnArchive.GetName();
\r
649 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
\r
650 if (! swInfo.fnDestinationDirectory.IsOk())
\r
652 ::ErrDlg(_("Unable to make the temporary directory!"), this);
\r
658 mkDlg.InitDialog();
\r
659 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
665 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
666 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
667 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
668 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
670 // 必要なら書庫名でディレクトリを作成する。
\r
671 if (WillMakeDirByArcName(this, & mkDlg))
\r
673 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
674 if (! swInfo.fnDestinationDirectory.IsOk())
\r
676 ::ErrDlg(_("Unable to make the destination directory!"), this);
\r
682 ProcessDialog procDlg;
\r
683 procDlg.InitDialog();
\r
684 procDlg.Show(true);
\r
685 if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
\r
687 this->ErrorCheck(tpi.nErrorCode);
\r
689 procDlg.Show(false);
\r
693 if (mkDlg.cbOpenAfter->IsChecked())
\r
697 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
\r
701 if (mkDlg.cbExitAfter->IsChecked())
\r
709 wxArrayString asFiles;
\r
713 asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
\r
714 if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
\r
717 // Linuxでは引用符で囲む必要がある。
\r
718 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
\r
720 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
\r
727 wxFileDataObject objFile;
\r
728 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
730 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
\r
734 objFile.AddFile(szFileName);
\r
736 asFiles.Add(szFileName);
\r
740 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
\r
744 wxDropSource dropSource(objFile, this);
\r
745 if (dropSource.DoDragDrop() != wxDragMove)
\r
748 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
754 // ファイルと一時ディレクトリを削除。
\r
755 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
757 ::wxRemoveFile(asFiles[i]);
\r
759 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
\r
763 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
765 // 全ファイル削除は危険ではないかと。
\r
766 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
771 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
777 TPI_SWITCHES swInfo;
\r
778 ProcessDialog procDlg;
\r
779 procDlg.InitDialog();
\r
780 procDlg.Show(true);
\r
781 if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
783 this->ErrorCheck(tpi.nErrorCode);
\r
785 procDlg.Show(false);
\r
788 this->OnArcOpen(e);
\r
791 void MainFrame::OnArcTest(wxCommandEvent&)
\r
793 TPI_SWITCHES swInfo;
\r
794 ProcessDialog procDlg;
\r
795 procDlg.InitDialog();
\r
796 procDlg.Show(true);
\r
797 if (this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
799 ::MsgDlg(_("This is a correct archive."), & procDlg, wxICON_INFORMATION);
\r
803 this->ErrorCheck(tpi.nErrorCode);
\r
805 procDlg.Show(false);
\r
808 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
810 TPI_SWITCHES swInfo;
\r
811 ProcessDialog procDlg;
\r
812 procDlg.InitDialog();
\r
813 procDlg.Show(true);
\r
814 if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
\r
816 this->ErrorCheck(tpi.nErrorCode);
\r
818 procDlg.Show(false);
\r
821 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
824 this->menubar->Check(n, true);
\r
825 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
826 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
827 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
830 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
832 this->toolbar->Show(e.IsChecked());
\r
835 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
837 this->statusbar->Show(e.IsChecked());
\r
840 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
842 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
844 this->list_ctrl->Select(i, true);
\r
850 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
853 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
855 this->list_ctrl->showFileInfo.Clear();
\r
856 this->list_ctrl->DeleteAllItems();
\r
857 g_hIconLL.RemoveAll();
\r
858 g_hIconLS.RemoveAll();
\r
860 // 現在のアイテムの選択状態を無効にしておく。
\r
861 long nSelected = this->list_ctrl->GetFirstSelected();
\r
862 while (nSelected != -1)
\r
864 this->list_ctrl->Select(nSelected, false);
\r
865 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
869 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
870 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
872 // 配列と比較し、パスが一致しなければ消す。
\r
873 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
876 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
879 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
885 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
890 this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
\r
895 this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
\r
896 this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
\r
899 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
901 // TODO : アイテムが子階層を持っていても展開できない。
\r
902 this->tree_ctrl->SelectItem(e.GetItem());
\r
906 this->OnArcExtract(e1);
\r
911 void MainFrame::OnListItemDClick(wxListEvent&)
\r
915 this->OnArcExtract(e);
\r
918 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
920 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
922 // アイテムを選択せずドラッグしようとした場合。
\r
928 this->OnArcExtract(e);
\r
933 void MainFrame::OnFilter(wxCommandEvent&)
\r
936 e.SetItem(this->tree_ctrl->GetSelection());
\r
937 this->OnTreeChanged(e);
\r
942 wxULongLong MainFrame::LoadTPI(wxString szFileName)
\r
946 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
947 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
948 wxULongLong llFileCount = 0;
\r
949 while (! szTPIName.IsEmpty())
\r
952 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)
\r
955 szTPIName = fs.FindNext();
\r
960 return llFileCount;
\r
963 int MainFrame::ErrorCheck(int nErrorCode)
\r
965 switch (nErrorCode)
\r
967 case TPI_ERROR_SUCCESS:
\r
968 case TPI_CALLBACK_CONTINUE:
\r
970 case TPI_ERROR_D_UNSUPPORTED:
\r
971 ::ErrDlg(_("Sorry, this function is not supported yet."), this);
\r
973 case TPI_ERROR_D_SKIPPED:
\r
974 case TPI_CALLBACK_CANCEL:
\r
975 ::ErrDlg(_("This operation is canceled by the user."), this);
\r
978 ::ErrDlg(_("Error code: ") + wxString::Format(wxT("%d"), nErrorCode), this);
\r