-/*******************************************************************************
- TPI - flexible but useless plug-in framework.
- Copyright (C) 2002-2009 Silky
-
- This library is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 2.1 of the License, or (at your option)
- any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- for more details.
-
- You should have received a copy of the GNU Lesser General Public License along
- with this library; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- $Id$
-*******************************************************************************/
-
-#include "lychee.h"
-
-#include "frm_main.h"
-#include "cls_filedroptarget.h"
-#include "dlg_make.h"
-#include "dlg_process.h"
-#include "functions.h"
-
-#include <wx/arrimpl.cpp>
-
-WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);
-
-#define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)
-
-//******************************************************************************
-// \83O\83\8d\81[\83o\83\8b\95Ï\90\94
-//******************************************************************************
-
-wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);
-int g_nSortColumn;
-bool g_fSortAscend;
-
-//******************************************************************************
-// MainFrame
-//******************************************************************************
-
-MainFrame::MainFrame(): wxFrame(), conf(wxEmptyString, wxEmptyString, L_DIR_BIN wxT("lychee.conf"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH)
-{
-}
-
-MainFrame::~MainFrame()
-{
- wxCommandEvent e;
- this->OnArcClose(e);
-
- // \90Ý\92è\82ð\8bL\98^\81B
- if (! this->IsIconized() && ! this->IsMaximized())
- {
- int a, b;
- this->GetSize(& a, & b);
- this->conf.Write(wxT("Window-Width"), a);
- this->conf.Write(wxT("Window-Height"), b);
- this->GetPosition(& a, & b);
- this->conf.Write(wxT("Window-X"), a);
- this->conf.Write(wxT("Window-Y"), b);
- }
- this->conf.Write(wxT("Splitter-Pos"), this->window_splitter->GetSashPosition());
-
- // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\8aÖ\98A\81B
- this->conf.Write(wxT("StatusBar-Show"), this->statusbar->IsShown());
- this->conf.Write(wxT("ToolBar-Show"), this->toolbar->IsShown());
-
- // ListView\8aÖ\98A\81B
- this->conf.Write(wxT("ListView-IconMode"), this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);
- if (this->menubar->IsChecked(XRCID("Exe_View_Details")))
- {
- this->conf.Write(wxT("ListView-C-Filename"), this->list_ctrl->GetColumnWidth(0));
- this->conf.Write(wxT("ListView-C-Unpacked"), this->list_ctrl->GetColumnWidth(1));
- this->conf.Write(wxT("ListView-C-Packed"), this->list_ctrl->GetColumnWidth(2));
- this->conf.Write(wxT("ListView-C-Ratio"), this->list_ctrl->GetColumnWidth(3));
- this->conf.Write(wxT("ListView-C-Method"), this->list_ctrl->GetColumnWidth(4));
- this->conf.Write(wxT("ListView-C-Attr"), this->list_ctrl->GetColumnWidth(5));
- this->conf.Write(wxT("ListView-C-Lastmodified"), this->list_ctrl->GetColumnWidth(6));
- this->conf.Write(wxT("ListView-C-Path"), this->list_ctrl->GetColumnWidth(7));
- this->conf.Write(wxT("ListView-C-Type"), this->list_ctrl->GetColumnWidth(8));
- this->conf.Write(wxT("ListView-C-No"), this->list_ctrl->GetColumnWidth(9));
- this->conf.Write(wxT("ListView-SortColumn"), g_nSortColumn);
- this->conf.Write(wxT("ListView-SortAscend"), g_fSortAscend);
- }
-
- this->Close(true);
-}
-
-//******************************************************************************
-// Event Table.
-//******************************************************************************
-
-BEGIN_EVENT_TABLE(MainFrame, wxFrame)
- EVT_INIT_DIALOG( MainFrame::OnInit)
- // Menu
- EVT_MENU(XRCID("Arc_Create"), MainFrame::OnArcCreate)
- EVT_MENU(XRCID("Arc_Open"), MainFrame::OnArcOpen)
- EVT_MENU(XRCID("Arc_Close"), MainFrame::OnArcClose)
- EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)
- EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)
- EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)
- EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)
- EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
- EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)
- EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)
- EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)
- EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)
- EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
- EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)
- EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
- EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
- EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
- // TreeView
- EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
- EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
- // ListView
- EVT_LIST_ITEM_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)
- EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)
- // Filter
- EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
-END_EVENT_TABLE()
-
-//******************************************************************************
-// Event handler.
-//******************************************************************************
-
-void MainFrame::OnInit(wxInitDialogEvent&)
-{
- // XRC\82Æ\8c\8b\82Ñ\82Â\82¯\81B
- this->menubar = this->GetMenuBar();
- this->toolbar = this->GetToolBar();
- this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
- this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
- this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
- this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
- this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
-
- // \90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Ý\81B
- 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));
- wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
-
- // \8f\89\8aú\92l\90Ý\92è\81B
- {
- wxIcon icon;
- icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
- this->SetIcon(icon);
- }
- wxCommandEvent e;
- this->OnArcClose(e);
-
- // \83X\83v\83\8a\83b\83^\81[\90Ý\92è\81B
- this->window_splitter->SetSashPosition(this->conf.Read(wxT("Splitter-Pos"), 200));
-
- // \83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
- int nIconMode = this->conf.Read(wxT("ListView-IconMode"), 0l);
- e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
- this->OnViewMode(e);
- // wxGTK\82Å\82Í\92¼\90ÚwxLC_VIRTUAL\82ð\8ew\92è\82µ\82È\82¢\82Æ\94½\89f\82³\82ê\82È\82¢\81B
- this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
- this->list_ctrl->InsertColumn(0, wxT("Filename"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Filename"), 140));
- this->list_ctrl->InsertColumn(1, wxT("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Unpacked"), 80));
- this->list_ctrl->InsertColumn(2, wxT("Packed"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Packed"), 80));
- this->list_ctrl->InsertColumn(3, wxT("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Ratio"), 50));
- this->list_ctrl->InsertColumn(4, wxT("Method"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Method"), 60));
- this->list_ctrl->InsertColumn(5, wxT("Attr"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Attr"), 50));
- this->list_ctrl->InsertColumn(6, wxT("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-Lastmodified"), 150));
- this->list_ctrl->InsertColumn(7, wxT("Path"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Path"), 100));
- this->list_ctrl->InsertColumn(8, wxT("Type"), wxLIST_FORMAT_LEFT, this->conf.Read(wxT("ListView-C-Type"), 100));
- this->list_ctrl->InsertColumn(9, wxT("No."), wxLIST_FORMAT_RIGHT, this->conf.Read(wxT("ListView-C-No"), 35));
- g_nSortColumn = this->conf.Read(wxT("ListView-SortColumn"), 9);
- g_fSortAscend = this->conf.Read(wxT("ListView-SortAscend"), 1) == 1;
- this->list_ctrl->SetDropTarget(new myFileDropTarget(this));
-
- // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
- int nStatusBarParts[] = {70, 70, 180, 50, -1};
- this->statusbar->SetFieldsCount(5, nStatusBarParts);
- this->SetStatusBarPane(-1);
- bool fShow = this->conf.Read(wxT("StatusBar-Show"), 1) == 1;
- this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
- this->statusbar->Show(fShow);
- fShow = this->conf.Read(wxT("ToolBar-Show"), 1) == 1;
- this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
- this->toolbar->Show(fShow);
-
- // \83R\83}\83\93\83h\83\89\83C\83\93\93Ç\82Ý\8d\9e\82Ý\81B
- this->cmdLine.SetSwitchChars(wxT("-"));
- this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, wxT("(command) Extract filenames in archive."));
- this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, wxT("(command) List archive(default)."));
- this->cmdLine.AddParam(wxT("archive"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
- this->cmdLine.AddParam(wxT("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
- if (this->cmdLine.Parse() == 0)
- {
- if (this->cmdLine.GetParamCount() == 0)
- {
- return;
- }
-
- // \8f\91\8cÉ\82ð\8aJ\82\81B
- this->fnArchive = wxFileName(this->cmdLine.GetParam(0));
- this->fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);
- this->OnArcOpen(e);
- if (this->cmdLine.Found(wxT("x")))
- {
- // \8f\91\8cÉ\82ð\93W\8aJ\81B
- this->OnArcExtract(e);
- this->Close(true);
- }
- }
-}
-
-// MenuBar
-
-void MainFrame::OnExit(wxCommandEvent&)
-{
- this->Close(true);
-}
-
-void MainFrame::OnArcCreate(wxCommandEvent& e)
-{
- TPI_SWITCHES swInfo;
- swInfo.pCustomSwitches = NULL;
-
- // \8dì\90¬\83_\83C\83A\83\8d\83O\82ð\90Ý\92è\81B
- MakeDialog mkDlg;
- ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
- ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
-
- if (e.GetClientData() == NULL)
- {
- // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
- wxFileDialog fd(this, wxT("Choose files to compress"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
- if (fd.ShowModal() == wxID_CANCEL)
- {
- return;
- }
- swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
- this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
- this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);
-
- fd.GetFilenames(mkDlg.files);
- }
- else
- {
- mkDlg.files = * (wxArrayString *) e.GetClientData();
- swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
- // \91\8a\91Î\83p\83X\82É\95Ï\8a·\81B
- for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
- {
- wxFileName fn(mkDlg.files[n]);
- bool fIsDir = fn.DirExists() && ! fn.FileExists();
- fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
- mkDlg.files[n] = fn.GetFullPath();
- if (fIsDir)
- {
- mkDlg.files[n] += fn.GetPathSeparator();
- }
- }
- }
-
- this->OnArcClose(e);
- mkDlg.InitDialog();
- mkDlg.cbDir->SetValue(swInfo.fnDestinationDirectory.GetPath());
- // \8f\91\8cÉ\96¼\82Í\83t\83@\83C\83\8b\96¼\82Ì\8ag\92£\8eq\82æ\82è\91O\81A\82à\82µ\82\82Í\83f\83B\83\8c\83N\83g\83\8a\96¼\81B
- this->fnArchive = wxFileName(mkDlg.files[0]);
- this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
- this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
- mkDlg.cbFileName->SetValue(this->fnArchive.GetName());
-
- // \83_\83C\83A\83\8d\83O\82ð\95\\8e¦\81B
- if (mkDlg.ShowModal() == wxID_CANCEL)
- {
- this->statusbar->SetStatusText(wxEmptyString, 4);
- return;
- }
- this->statusbar->SetStatusText(wxEmptyString, 4);
-
- // \8ae\8eí\90Ý\92è\81B
- swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
- swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
- swInfo.fSolid = mkDlg.cbSolid->IsChecked();
- swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
- swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
- swInfo.sCompressLevel = mkDlg.scLevel->GetValue();
- swInfo.sRecoveryRecord = mkDlg.scRR->GetValue();
- swInfo.szPassword = mkDlg.tcPassword->GetValue();
- swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
- swInfo.szComment = mkDlg.tcComment->GetValue();
- {
- wxULongLong_t ll;
- mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
- swInfo.llSplitSize = ll;
- }
-
- // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
- int nSelected = mkDlg.chType->GetSelection();
- this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue(), swInfo.fMakeSFX ? EXE_EXT : mkDlg.afInfo[nSelected].szSuffix.BeforeFirst(wxT(';')));
- if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
- {
- ::ErrDlg(wxT("InitLibrary()!"), this);
- return;
- }
-
- // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
- if (! tpi.SetCallbackProc(TPICallbackProc))
- {
- ::ErrDlg(wxT("SetCallbackProc()!"), this);
- }
-
- // \8f\88\97\9d\82ð\8ds\82¤\81B
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
- {
- this->ErrorCheck(tpi.nErrorCode);
- return;
- }
- procDlg.Show(false);
- tpi.FreeLibrary();
-
- if (mkDlg.cbOpenAfter->IsChecked())
- {
- // \8dì\90¬\90æ\82ð\8aJ\82\81B
-#ifdef __WINDOWS__
- ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
-#endif
- }
-
- if (mkDlg.cbExitAfter->IsChecked())
- {
- // \8fI\97¹\81B
- this->Close(true);
- }
-
- // \8fI\97¹\82µ\82È\82¢\8fê\8d\87\82Í\8f\91\8cÉ\82ð\8aJ\82\81B
- this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcOpen(wxCommandEvent& e)
-{
- // \8f\91\8cÉ\82ð\91I\91ð\81B
- if (e.GetId() == XRCID("Arc_Open"))
- {
- wxFileDialog fd(this);
- fd.SetDirectory(this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
- if (fd.ShowModal() == wxID_CANCEL)
- {
- return;
- }
- this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
- this->fnArchive = wxFileName(fd.GetPath());
- }
- this->OnArcClose(e);
-
- // \90i\92»\83_\83C\83A\83\8d\83O\95\\8e¦\81B
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
-
- // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81A\8dÅ\8f\89\82Ì\83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B
- TPI_PROCESSINFO piInfo;
- piInfo.uMessage = TPI_MESSAGE_STATUS;
- piInfo.uStatus = 0x1000;
- piInfo.llProcessedSize = 0;
- piInfo.fiInfo.fnFileName = this->fnArchive;
- piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
- if ((signed) piInfo.fiInfo.llUnpackedSize.ToULong() == -1)
- {
- procDlg.Show(false);
- tpi.FreeLibrary();
- ::ErrDlg(wxT("No plug-in supporting this archive was found!"), this);
- return;
- }
- TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
-
- // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
- tpi.SetCallbackProc(TPICallbackProc);
-
- // \94z\97ñ\82Ì\83T\83C\83Y\82ð\8am\95Û\81B
- this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
-
- // \8f\91\8cÉ\82ð\8aJ\82\81B
- if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
- {
- procDlg.Show(false);
- tpi.FreeLibrary();
- ::ErrDlg(wxT("OpenArchive()!"), this);
- return;
- }
-
- // \8f\91\8cÉ\82Ì\83A\83C\83R\83\93\82ð\8eæ\93¾\82µ\81A\8f\91\8cÉ\83\8b\81[\83g\82ð\8dì\90¬\81B
- g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
- g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
- this->tree_ctrl->SetImageList(& g_hIconT);
- wxTreeItemId
- idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
-#ifdef __WINDOWS__
- idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
-#else
- idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
-#endif
- idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
-
- // \83t\83@\83C\83\8b\8fî\95ñ\82ð\83\8d\81[\83h\81B
- if (tpi.GetFileInformation(& piInfo.fiInfo, true))
- {
- piInfo.uStatus = 0x1001;
- do
- {
- piInfo.llProcessedSize++;
- if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
- {
- procDlg.Show(false);
- tpi.CloseArchive();
- wxCommandEvent e;
- this->OnArcClose(e);
- return;
- }
-
- // \83c\83\8a\81[\83r\83\85\81[\82É\94½\89f\81B
- TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
-
- // \83f\83B\83\8c\83N\83g\83\8a\91®\90«\82ð\8aÜ\82Þ\82à\82Ì\82É\82Â\82¢\82Ä\82Í\8f\9c\8b\8e\81B
- if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
- {
- continue;
- }
-
- // \83Z\83L\83\85\83\8a\83e\83B\83`\83F\83b\83N\81B
- // DTV\8c\9f\8d¸\81B
- if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
- {
- piInfo.fiInfo.uDanger = TRUE;
- ::WrnDlg(wxT("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);
- }
- // \8bó\94\92\82Ì\98A\91±\82É\82æ\82é\8ag\92£\8eq\8bU\91\95\82ð\8c\9f\8d¸\81B
- if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
- {
- piInfo.fiInfo.uDanger = TRUE;
- ::WrnDlg(wxT("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);
- }
- // Unicode\90§\8cä\95¶\8e\9a\82ð\8c\9f\8d¸\81B
- for (wxChar c = 0x200c; c <= 0x206f; c++)
- {
- if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
- {
- piInfo.fiInfo.uDanger = TRUE;
- ::WrnDlg(wxT("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);
- }
- switch (c)
- {
- case 0x200f: c = 0x2027; break;
- case 0x202e: c = 0x2060; break;
- }
- }
-
- // \8fî\95ñ\82ð\95Û\91¶\82µ\82Ä\83J\83E\83\93\83g\83A\83b\83v\81B
- this->fileinfo.Add(piInfo.fiInfo);
- }
- while (tpi.GetFileInformation(& piInfo.fiInfo, false));
- }
-
- // \8f\91\8cÉ\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B
- TPI_ARCHIVEINFO aiInfo;
- if (! tpi.GetArchiveInformation(& aiInfo))
- {
- procDlg.Show(false);
- tpi.FreeLibrary();
- ::ErrDlg(wxT("GetArchiveInformation()!"), this);
- return;
- }
- this->szComment = aiInfo.szComment;
-
- // \8f\91\8cÉ\82ð\95Â\82¶\82é\81B
- if (! tpi.CloseArchive())
- {
- ::ErrDlg(wxT("CloseArchive()!"), this);
- }
-
- // \88È\89º\81AUI\8f\88\97\9d\81B
- this->fileinfo.Shrink();
- this->tree_ctrl->ExpandAll();
- this->tree_ctrl->ScrollTo(idArchive);
- this->tree_ctrl->SelectItem(idArchive);
- this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
-
- // \83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
- this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
- this->statusbar->SetStatusText(wxString::Format(wxT("%d file(s)"), this->fileinfo.GetCount()), 1);
- this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + wxT(" B -> ") + aiInfo.llPackedSize.ToString() + wxT(" B"), 2);
- this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
- this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
-
- // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
- SetMenuToolState("Arc_Close", true);
- SetMenuToolState("Arc_Add", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && aiInfo.fiInfo.fArchive);
- SetMenuToolState("Arc_SFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && aiInfo.nSFXType == 0);
- SetMenuToolState("Arc_UnSFX", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
- SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
- SetMenuToolState("Arc_Delete", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && aiInfo.fiInfo.fArchive);
- SetMenuToolState("Arc_Test", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
- SetMenuToolState("Arc_Repair", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
-
- procDlg.Show(false);
-}
-
-void MainFrame::OnArcClose(wxCommandEvent&)
-{
- // \83c\83\8a\81[\83r\83\85\81[\81E\83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
- this->tree_ctrl->DeleteAllItems();
- this->list_ctrl->DeleteAllItems();
- this->list_ctrl->showFileInfo.Clear();
-
- // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
- SetMenuToolState("Arc_Close", false);
- SetMenuToolState("Arc_Add", false);
- SetMenuToolState("Arc_SFX", false);
- SetMenuToolState("Arc_UnSFX", false);
- SetMenuToolState("Arc_Extract", false);
- SetMenuToolState("Arc_Delete", false);
- SetMenuToolState("Arc_Test", false);
- SetMenuToolState("Arc_Repair", false);
-
- for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
- {
- this->statusbar->SetStatusText(wxEmptyString, i);
- }
- this->fileinfo.Clear();
- this->szComment.Clear();
-
- g_hIconT.RemoveAll();
- g_hIconLL.RemoveAll();
- g_hIconLS.RemoveAll();
- this->tpi.FreeLibrary();
-}
-
-void MainFrame::OnArcAdd(wxCommandEvent& e)
-{
- // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
- wxArrayString files;
- wxFileDialog fd(this, wxT("Choose files to add"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
- if (fd.ShowModal() == wxID_CANCEL)
- {
- return;
- }
- fd.GetFilenames(files);
- this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-
- // \8ae\8eí\90Ý\92è\81B
- TPI_SWITCHES swInfo;
- swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
- swInfo.fMakeSFX = false;
- swInfo.pCustomSwitches = NULL;
-
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-
- // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\81B
- this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcConvert(wxCommandEvent& e)
-{
- TPI_SWITCHES swInfo;
- swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
-
- // \95Û\91¶\90æ\82ð\90q\82Ë\82é\81B
- wxFileDialog fd(this, swInfo.fMakeSFX ? wxT("Save as SFX") : wxT("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString));
- fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
- if (fd.ShowModal() == wxID_CANCEL)
- {
- return;
- }
- swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
- this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-
- wxArrayString files;
- files.Add(fd.GetPath());
-
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-}
-
-void MainFrame::OnArcExtract(wxCommandEvent& e)
-{
- TPI_SWITCHES swInfo;
- swInfo.pCustomSwitches = NULL;
-
- // \83\82\81[\83h\8eæ\93¾\81B\92Ê\8fí\82Í0, \8eÀ\8ds\82È\82ç1, \83t\83@\83C\83\8bDnD\82È\82ç2\81A\83f\83B\83\8c\83N\83g\83\8aDnD\82È\82ç3\81B
- int nMode = e.GetInt();
- // \8eÀ\8ds\8e\9e\82Ì\82Ý\8eg\97p\81B
- wxFileType * ftFile = NULL;
-
- // \93W\8aJ\83_\83C\83A\83\8d\83O\82ð\8dì\90¬\81BDnD\82Ü\82½\82Í\8eÀ\8ds\8e\9e\82Í\95\\8e¦\82µ\82È\82¢\81B
- MakeDialog mkDlg;
- ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
- ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
- mkDlg.bIsMake = false;
- mkDlg.files = MakeTargetFileList(this, nMode == 1);
-
- if (nMode != 0)
- {
- if (nMode == 1)
- {
- // \83R\83}\83\93\83h\82ð\8eæ\93¾\81B
- ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
- if (! ftFile)
- {
- // \8eí\97Þ\82ª\8eæ\93¾\82Å\82«\82È\82¢\82Æ\82«\82Í\90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Þ\81B\8f\89\8aú\90Ý\92è\82Å\82Í\83e\83L\83X\83g\82Æ\82Ý\82È\82·\81B
- ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.Read(wxT("DefaultExt"), wxT("txt")));
- if (! ftFile)
- {
- ::ErrDlg(wxT("Unable to get the file type!"), this);
- return;
- }
- }
- }
-
- // \8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\8dì\90¬\81B
- swInfo.fStoreDirectoryPathes = false;
- wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
- if (szDestDirBase == wxT("-----"))
- {
- // \8f\91\8cÉ\83\8b\81[\83g\82Ì\82Æ\82«\82Í\8f\91\8cÉ\96¼\82É\82µ\82Ä\82¨\82\81B
- szDestDirBase = this->fnArchive.GetName();
- }
- swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
- if (! swInfo.fnDestinationDirectory.IsOk())
- {
- ::ErrDlg(wxT("Unable to make the temporary directory!"), this);
- return;
- }
- }
- else
- {
- mkDlg.InitDialog();
- if (mkDlg.ShowModal() == wxID_CANCEL)
- {
- return;
- }
-
- // \8ae\8eí\90Ý\92è\81B
- swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
- swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
- swInfo.szPassword = mkDlg.tcPassword->GetValue();
- swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
-
- // \95K\97v\82È\82ç\8f\91\8cÉ\96¼\82Å\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\82·\82é\81B
- if (WillMakeDirByArcName(this, & mkDlg))
- {
- swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
- if (! swInfo.fnDestinationDirectory.IsOk())
- {
- ::ErrDlg(wxT("Unable to make the destination directory!"), this);
- return;
- }
- }
- }
-
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-
- if (nMode == 0)
- {
- if (mkDlg.cbOpenAfter->IsChecked())
- {
- // \93W\8aJ\90æ\82ð\8aJ\82\81B
-#ifdef __WINDOWS__
- ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
-#endif
- }
-
- if (mkDlg.cbExitAfter->IsChecked())
- {
- // \8fI\97¹\81B
- this->Close(true);
- }
- }
- else
- {
- wxArrayString asFiles;
- if (nMode == 1)
- {
- // \83R\83}\83\93\83h\82ð\8eÀ\8ds\81B
- asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
- if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
- {
-#ifdef __LINUX__
- // Linux\82Å\82Í\88ø\97p\95\84\82Å\88Í\82Þ\95K\97v\82ª\82 \82é\81B
- ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
-#else
- ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
-#endif
- }
- }
- else
- {
- // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
- wxFileDataObject objFile;
- for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
- {
- wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
- if (nMode == 2)
- {
- // \83\8a\83X\83g\82É\92Ç\89Á\81B
- objFile.AddFile(szFileName);
- }
- asFiles.Add(szFileName);
- }
- if (nMode == 3)
- {
- objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
- }
-
- // DnD\8aJ\8en\81B
- wxDropSource dropSource(objFile, this);
- if (dropSource.DoDragDrop() != wxDragMove)
- {
-#ifdef __LINUX__
- // Linux\82Å\82Í\82Ü\82¾\8f\88\97\9d\82ª\8fI\82í\82Á\82Ä\82¢\82È\82¢(\83R\83\93\83e\83L\83X\83g\83\81\83j\83\85\81[\82ª\95\\8e¦\82³\82ê\82Ä\82¢\82é)\82Ì\82Å\81A\82Æ\82è\82 \82¦\82¸3\95b\82¾\82¯\91Ò\82Â\81B
- sleep(3);
-#endif
- }
- }
-
- // \83t\83@\83C\83\8b\82Æ\88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
- for (size_t i = 0; i < asFiles.GetCount(); i++)
- {
- ::wxRemoveFile(asFiles[i]);
- }
- ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
- }
-}
-
-void MainFrame::OnArcDelete(wxCommandEvent& e)
-{
- // \91S\83t\83@\83C\83\8b\8dí\8f\9c\82Í\8aë\8c¯\82Å\82Í\82È\82¢\82©\82Æ\81B
- if (this->list_ctrl->GetSelectedItemCount() == 0)
- {
- return;
- }
-
- if (::AskDlg(wxT("Are you sure to delete selected files?"), this) == wxNO)
- {
- return;
- }
-
- // \8ae\8eí\90Ý\92è\81B
- TPI_SWITCHES swInfo;
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-
- // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\82·\82é\81B
- this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcTest(wxCommandEvent&)
-{
- TPI_SWITCHES swInfo;
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
- {
- ::MsgDlg(wxT("This is a correct archive."), & procDlg, wxICON_INFORMATION);
- }
- else
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-}
-
-void MainFrame::OnArcRepair(wxCommandEvent&)
-{
- TPI_SWITCHES swInfo;
- ProcessDialog procDlg;
- procDlg.InitDialog();
- procDlg.Show(true);
- if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
- {
- this->ErrorCheck(tpi.nErrorCode);
- }
- procDlg.Show(false);
-}
-
-void MainFrame::OnViewMode(wxCommandEvent & e)
-{
- int n = e.GetId();
- this->menubar->Check(n, true);
- this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
- this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
- this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
-}
-
-void MainFrame::OnShowToolBar(wxCommandEvent & e)
-{
- this->toolbar->Show(e.IsChecked());
-}
-
-void MainFrame::OnShowStatusBar(wxCommandEvent & e)
-{
- this->statusbar->Show(e.IsChecked());
-}
-
-void MainFrame::OnSelectAll(wxCommandEvent &)
-{
- for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
- {
- this->list_ctrl->Select(i, true);
- }
-}
-
-// TreeView
-
-void MainFrame::OnTreeChanged(wxTreeEvent& e)
-{
- // \83c\83\8a\81[\83r\83\85\81[\82©\82ç\83p\83X\82ð\8eæ\93¾\81B
- wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
- // \83\8a\83X\83g\83r\83\85\81[\82ð\8f\89\8aú\89»\81B
- this->list_ctrl->showFileInfo.Clear();
- this->list_ctrl->DeleteAllItems();
- g_hIconLL.RemoveAll();
- g_hIconLS.RemoveAll();
-
- // \8c»\8dÝ\82Ì\83A\83C\83e\83\80\82Ì\91I\91ð\8fó\91Ô\82ð\96³\8cø\82É\82µ\82Ä\82¨\82\81B
- long nSelected = this->list_ctrl->GetFirstSelected();
- while (nSelected != -1)
- {
- this->list_ctrl->Select(nSelected, false);
- nSelected = this->list_ctrl->GetNextSelected(nSelected);
- }
-
- // \83A\83C\83R\83\93\90Ý\92è\81B
- this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
- this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
-
- // \94z\97ñ\82Æ\94ä\8ar\82µ\81A\83p\83X\82ª\88ê\92v\82µ\82È\82¯\82ê\82Î\8fÁ\82·\81B
- for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
- {
- // \83p\83X\82ð\94ä\8ar\81B
- if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
- {
- // \8d\80\96Ú\82ª\83t\83H\83\8b\83_\82Å\82 \82é\82È\82ç\96³\8e\8b\81B
- 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))
- {
- continue;
- }
-
- // \83t\83B\83\8b\83^\82É\82©\82©\82ç\82È\82¯\82ê\82Î\96³\8e\8b\81B
- if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
- {
- continue;
- }
-
- this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
- }
- }
-
- // \83\\81[\83g\82µ\82Ä\95\\8e¦\81B
- this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
- this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
-}
-
-void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
-{
- // TODO : \83A\83C\83e\83\80\82ª\8eq\8aK\91w\82ð\8e\9d\82Á\82Ä\82¢\82Ä\82à\93W\8aJ\82Å\82«\82È\82¢\81B
- this->tree_ctrl->SelectItem(e.GetItem());
-
- wxCommandEvent e1;
- e1.SetInt(3);
- this->OnArcExtract(e1);
-}
-
-// ListView
-
-void MainFrame::OnListItemDClick(wxListEvent&)
-{
- wxCommandEvent e;
- e.SetInt(1);
- this->OnArcExtract(e);
-}
-
-void MainFrame::OnListBeginDrag(wxListEvent&)
-{
- if (this->list_ctrl->GetSelectedItemCount() == 0)
- {
- // \83A\83C\83e\83\80\82ð\91I\91ð\82¹\82¸\83h\83\89\83b\83O\82µ\82æ\82¤\82Æ\82µ\82½\8fê\8d\87\81B
- return;
- }
-
- wxCommandEvent e;
- e.SetInt(2);
- this->OnArcExtract(e);
-}
-
-// Filter
-
-void MainFrame::OnFilter(wxCommandEvent&)
-{
- wxTreeEvent e;
- e.SetItem(this->tree_ctrl->GetSelection());
- this->OnTreeChanged(e);
-}
-
-// \83C\83x\83\93\83g\83n\83\93\83h\83\89\88È\8aO\81B
-
-int MainFrame::LoadTPI(wxString szFileName)
-{
- // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
- wxFileSystem fs;
- fs.ChangePathTo(L_DIR_B_LIB, true);
- wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
- int nFileCount = -1;
- while (! szTPIName.IsEmpty())
- {
- // \91Î\89\9e\8am\94F\81B
- if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & nFileCount) || nFileCount < 0)
- {
- tpi.FreeLibrary();
- szTPIName = fs.FindNext();
- continue;
- }
- break;
- }
- return nFileCount;
-}
-
-int MainFrame::ErrorCheck(int nErrorCode)
-{
- switch (nErrorCode)
- {
- case TPI_ERROR_SUCCESS:
- case TPI_CALLBACK_CONTINUE:
- break;
- case TPI_ERROR_D_UNSUPPORTED:
- ::ErrDlg(wxT("Sorry, this function is not supported yet."), this);
- break;
- case TPI_ERROR_D_SKIPPED:
- case TPI_CALLBACK_CANCEL:
- ::ErrDlg(wxT("This operation is canceled by the user."), this);
- break;
- default:
- ::ErrDlg(wxT("Error code is ") + wxString::Format(wxT("%d."), nErrorCode), this);
- }
- return nErrorCode;
-}
+/*******************************************************************************\r
+ TPI - flexible but useless plug-in framework.\r
+ Copyright (C) 2002-2009 Silky\r
+\r
+ This library is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU Lesser General Public License as published by the Free\r
+ Software Foundation; either version 2.1 of the License, or (at your option)\r
+ any later version.\r
+\r
+ This library is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License\r
+ for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License along\r
+ with this library; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+\r
+ $Id$\r
+*******************************************************************************/\r
+\r
+#include "lychee.h"\r
+\r
+#include "frm_main.h"\r
+#include "cls_filedroptarget.h"\r
+#include "dlg_make.h"\r
+#include "dlg_process.h"\r
+#include "functions.h"\r
+\r
+#include <wx/arrimpl.cpp>\r
+\r
+WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);\r
+\r
+#define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)\r
+\r
+//******************************************************************************\r
+// グローバル変数\r
+//******************************************************************************\r
+\r
+wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);\r
+int g_nSortColumn;\r
+bool g_fSortAscend;\r
+\r
+//******************************************************************************\r
+// MainFrame\r
+//******************************************************************************\r
+\r
+MainFrame::MainFrame(): wxFrame()\r
+{\r
+}\r
+\r
+MainFrame::~MainFrame()\r
+{\r
+ wxCommandEvent e;\r
+ this->OnArcClose(e);\r
+\r
+ // 設定を記録。\r
+ if (! this->IsIconized() && ! this->IsMaximized())\r
+ {\r
+ int a, b;\r
+ this->GetSize(& a, & b);\r
+ this->conf.WriteId(CONF_WINDOW_WIDTH, a);\r
+ this->conf.WriteId(CONF_WINDOW_HEIGHT, b);\r
+ this->GetPosition(& a, & b);\r
+ this->conf.WriteId(CONF_WINDOW_X, a);\r
+ this->conf.WriteId(CONF_WINDOW_Y, b);\r
+ }\r
+ this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());\r
+\r
+ // ツールバー/ステータスバー関連。\r
+ this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());\r
+ this->conf.WriteId(CONF_WINDOW_TOOLBAR, this->toolbar->IsShown());\r
+\r
+ // ListView関連。\r
+ this->conf.WriteId(CONF_LISTVIEW_SHOWMODE, this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);\r
+ if (this->menubar->IsChecked(XRCID("Exe_View_Details")))\r
+ {\r
+ this->conf.WriteId(CONF_LISTVIEW_C_FILENAME, this->list_ctrl->GetColumnWidth(0));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED, this->list_ctrl->GetColumnWidth(1));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_PACKED, this->list_ctrl->GetColumnWidth(2));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_RATIO, this->list_ctrl->GetColumnWidth(3));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_METHOD, this->list_ctrl->GetColumnWidth(4));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_ATTR, this->list_ctrl->GetColumnWidth(5));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD, this->list_ctrl->GetColumnWidth(6));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_PATH, this->list_ctrl->GetColumnWidth(7));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_TYPE, this->list_ctrl->GetColumnWidth(8));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_NO, this->list_ctrl->GetColumnWidth(9));\r
+ this->conf.WriteId(CONF_LISTVIEW_C_COMMENT, this->list_ctrl->GetColumnWidth(10));\r
+ this->conf.WriteId(CONF_LISTVIEW_S_COLUMN, g_nSortColumn);\r
+ this->conf.WriteId(CONF_LISTVIEW_S_ASCEND, g_fSortAscend);\r
+ }\r
+\r
+ this->Close(true);\r
+}\r
+\r
+//******************************************************************************\r
+// Event Table.\r
+//******************************************************************************\r
+\r
+BEGIN_EVENT_TABLE(MainFrame, wxFrame)\r
+ EVT_INIT_DIALOG( MainFrame::OnInit)\r
+ // Menu\r
+ EVT_MENU(XRCID("Arc_Create"), MainFrame::OnArcCreate)\r
+ EVT_MENU(XRCID("Arc_Open"), MainFrame::OnArcOpen)\r
+ EVT_MENU(XRCID("Arc_Close"), MainFrame::OnArcClose)\r
+ EVT_MENU(XRCID("Arc_Clone"), MainFrame::OnArcClone)\r
+ EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)\r
+ EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)\r
+ EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)\r
+ EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)\r
+ EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)\r
+ EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)\r
+ EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)\r
+ EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)\r
+ EVT_MENU(XRCID("Exe_Copy"), MainFrame::OnExeCopy)\r
+ EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)\r
+ EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)\r
+ EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)\r
+ EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)\r
+ EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)\r
+ EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)\r
+ // TreeView\r
+ EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)\r
+ EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)\r
+ EVT_COMMAND_CONTEXT_MENU(XRCID("TreeView"), MainFrame::OnContextMenu)\r
+ // ListView\r
+ EVT_LIST_ITEM_SELECTED( XRCID("ListView"), MainFrame::OnListItemSelect)\r
+ EVT_LIST_ITEM_DESELECTED(XRCID("ListView"), MainFrame::OnListItemSelect)\r
+ EVT_LIST_ITEM_ACTIVATED( XRCID("ListView"), MainFrame::OnListItemDClick)\r
+ EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)\r
+ EVT_COMMAND_CONTEXT_MENU(XRCID("ListView"), MainFrame::OnContextMenu)\r
+ // Filter\r
+ EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)\r
+END_EVENT_TABLE()\r
+\r
+//******************************************************************************\r
+// Event handler.\r
+//******************************************************************************\r
+\r
+void MainFrame::OnInit(wxInitDialogEvent&)\r
+{\r
+ // XRCと結びつけ。\r
+ this->menubar = this->GetMenuBar();\r
+ this->toolbar = this->GetToolBar();\r
+ this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);\r
+ this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);\r
+ this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);\r
+ this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);\r
+ this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);\r
+\r
+ // 設定を読み込み。\r
+ this->SetSize(this->conf.ReadId(CONF_WINDOW_X, 0l), this->conf.ReadId(CONF_WINDOW_Y, 0l), this->conf.ReadId(CONF_WINDOW_WIDTH, 800l), this->conf.ReadId(CONF_WINDOW_HEIGHT, 400l), wxSIZE_ALLOW_MINUS_ONE);\r
+ wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);\r
+\r
+ // 初期値設定。\r
+ {\r
+ wxIcon icon;\r
+ icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));\r
+ this->SetIcon(icon);\r
+ }\r
+ wxCommandEvent e;\r
+ this->OnArcClose(e);\r
+ this->SetDropTarget(new myFileDropTarget(this));\r
+\r
+ // スプリッター設定。\r
+ this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));\r
+\r
+ // リストビュー設定。\r
+ int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);\r
+ e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));\r
+ this->OnViewMode(e);\r
+ // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。\r
+ this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);\r
+ this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));\r
+ this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED, 80l));\r
+ this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_PACKED, 80l));\r
+ this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_RATIO, 50l));\r
+ this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_METHOD, 60l));\r
+ this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_ATTR, 50l));\r
+ this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD, 150l));\r
+ this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_PATH, 100l));\r
+ this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_TYPE, 100l));\r
+ this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_NO, 35l));\r
+ this->list_ctrl->InsertColumn(10,_("Comment"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_COMMENT, 35l));\r
+ g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);\r
+ g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);\r
+\r
+ // ツールバー/ステータスバー設定。\r
+ int nStatusBarParts[] = {70, 70, 180, 50, -1};\r
+ this->statusbar->SetFieldsCount(5, nStatusBarParts);\r
+ this->SetStatusBarPane(-1);\r
+ bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);\r
+ this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);\r
+ this->statusbar->Show(fShow);\r
+ fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);\r
+ this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);\r
+ this->toolbar->Show(fShow);\r
+}\r
+\r
+// MenuBar\r
+\r
+void MainFrame::OnExit(wxCommandEvent&)\r
+{\r
+ this->Close(true);\r
+}\r
+\r
+void MainFrame::OnArcCreate(wxCommandEvent& e)\r
+{\r
+ TPI_SWITCHES swInfo;\r
+ swInfo.pCustomSwitches = NULL;\r
+\r
+ // 作成ダイアログを設定。\r
+ MakeDialog mkDlg;\r
+ ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+ ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+\r
+ if (e.GetClientData() == NULL)\r
+ {\r
+ // 処理対象のファイルを選択。\r
+ wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
+ if (fd.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+ swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+ fd.GetFilenames(mkDlg.files);\r
+ }\r
+ else\r
+ {\r
+ mkDlg.files = * (wxArrayString *) e.GetClientData();\r
+ swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());\r
+ // 相対パスに変換。\r
+ for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
+ {\r
+ wxFileName fn(mkDlg.files[n]);\r
+ fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
+ mkDlg.files[n] = fn.GetFullPath();\r
+ }\r
+ }\r
+\r
+ this->OnArcClose(e);\r
+ // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。\r
+ this->fnArchive = wxFileName(mkDlg.files[0]);\r
+ this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());\r
+ this->fnArchive.SetEmptyExt();\r
+ this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());\r
+\r
+ // ダイアログを表示。\r
+ if (mkDlg.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // 各種設定。\r
+ swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();\r
+ swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();\r
+ swInfo.fSolid = mkDlg.cbSolid->IsChecked();\r
+ swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();\r
+ swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();\r
+ swInfo.fCompressHeader = mkDlg.cbCompressHeader->IsChecked();\r
+ swInfo.nCompressLevel = mkDlg.scLevel->GetValue();\r
+ swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();\r
+ swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
+ swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();\r
+ swInfo.szComment = mkDlg.tcComment->GetValue();\r
+ mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);\r
+\r
+ // TPIを読み込み。\r
+ int nSelected = mkDlg.chType->GetSelection();\r
+ this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());\r
+ if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].nTypeId))\r
+ {\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));\r
+ return;\r
+ }\r
+\r
+ // コールバック関数を設定。\r
+ tpi.SetCallbackProc(TPICallbackProc);\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("SetCallbackProc"));\r
+\r
+ // 処理を行う。\r
+ {\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false);\r
+ }\r
+ tpi.FreeLibrary();\r
+\r
+ if (mkDlg.cbOpenAfter->IsChecked())\r
+ {\r
+ // 作成先を開く。\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+ }\r
+\r
+ if (mkDlg.cbExitAfter->IsChecked())\r
+ {\r
+ // 終了。\r
+ this->Close(true);\r
+ }\r
+\r
+ // 終了しない場合は書庫を開く。\r
+ this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcOpen(wxCommandEvent& e)\r
+{\r
+ // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。\r
+ int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;\r
+\r
+ // 書庫を選択。\r
+ if (nMode == 0)\r
+ {\r
+ wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
+ if (fd.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+ this->fnArchive = wxFileName(fd.GetPath());\r
+ }\r
+\r
+ // 進捗ダイアログ表示。\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+\r
+ // DnD以外で書庫を開く場合、TPIを読み込み。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.fiInfo.nUnpackedSize = e.GetExtraLong();\r
+ if (nMode != 2 && ! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))\r
+ {\r
+ procDlg.Show(false);\r
+ tpi.FreeLibrary();\r
+ if (this->IsShown())\r
+ {\r
+ wxBell();\r
+ this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);\r
+ }\r
+ else\r
+ {\r
+ wxLogError(_("No plug-in supporting this archive was found!"));\r
+ this->Close(true);\r
+ }\r
+ return;\r
+ }\r
+\r
+ // 最初のコールバックを送信。\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.nProcessedSize = 0;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ // 配列のサイズを確保。\r
+ this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);\r
+\r
+ // 履歴に追加。\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());\r
+ this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());\r
+ this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());\r
+\r
+ // 書庫のアイコンを取得し、書庫ルートを作成。\r
+ g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));\r
+ g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));\r
+ this->tree_ctrl->SetImageList(& g_hIconT);\r
+ wxTreeItemId\r
+ idRoot = this->tree_ctrl->AddRoot(wxEmptyString),\r
+#ifdef __WINDOWS__\r
+ idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),\r
+#else\r
+ idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),\r
+#endif\r
+ idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);\r
+\r
+ // ファイル情報をロード。\r
+ if (tpi.GetFileInformation(& piInfo.fiInfo, true))\r
+ {\r
+ piInfo.eStatus = 0x1001;\r
+ do\r
+ {\r
+ piInfo.nProcessedSize++;\r
+ if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)\r
+ {\r
+ procDlg.Show(false);\r
+ tpi.CloseArchive();\r
+ wxCommandEvent e;\r
+ this->OnArcClose(e);\r
+ return;\r
+ }\r
+\r
+ // 拡張子のみ設定されている場合。\r
+ if (piInfo.fiInfo.szStoredName.IsEmpty())\r
+ {\r
+ piInfo.fiInfo.szStoredName = this->fnArchive.GetName();\r
+ if (piInfo.fiInfo.fnFileName.HasExt())\r
+ {\r
+ piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();\r
+ }\r
+ piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);\r
+ }\r
+\r
+ // セキュリティチェック。\r
+ // ルート記号を削除。\r
+ wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);\r
+ if (szPath.StartsWith(wxT("/")))\r
+ {\r
+ piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);\r
+ }\r
+\r
+ // 改行文字/タブ文字などを削除。\r
+ if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND\r
+ || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND\r
+ || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)\r
+ {\r
+ wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();\r
+ sz.Replace(wxT("\r"), wxT(" "));\r
+ sz.Replace(wxT("\n"), wxT(" "));\r
+ sz.Replace(wxT("\t"), wxT(" "));\r
+ piInfo.fiInfo.eDanger = TRUE;\r
+ piInfo.fiInfo.fnFileName = wxFileName(sz);\r
+ wxLogWarning(_("This archive may contain files whose name contains some special characters like CR(\\r), LF(\\n), Tab(\\t) and some problem would be happen if you extract these files. Don\'t extract these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+ }\r
+\r
+ // DTV検査。\r
+ if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)\r
+ {\r
+ piInfo.fiInfo.eDanger = TRUE;\r
+ wxLogWarning(_("This archive may have Directory Traversal Vulnerability(DTV) problem, and some danger files may be extracted to the unexpected system directory! You should use the \"Ignore file pathes\" option when extracting this archive.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+ }\r
+ // 空白の連続による拡張子偽装を検査。\r
+ if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)\r
+ {\r
+ piInfo.fiInfo.eDanger = TRUE;\r
+ wxLogWarning(_("This archive may contain extension-disguised files whose real extension is hidden by using many blank charactor and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+ }\r
+ // Unicode制御文字を検査。\r
+ for (wxChar c = 0x200c; c <= 0x206f; c++)\r
+ {\r
+ if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)\r
+ {\r
+ piInfo.fiInfo.eDanger = TRUE;\r
+ wxLogWarning(_("This archive may contain extension-disguised files whose real extension is hidden by using Unicode control character and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+ }\r
+ switch (c)\r
+ {\r
+ case 0x200f: c = 0x2027; break;\r
+ case 0x202e: c = 0x2060; break;\r
+ }\r
+ }\r
+\r
+ // ツリービューに反映。\r
+ bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;\r
+ TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);\r
+\r
+ // ディレクトリ属性を含むものについては情報を保存しない。\r
+ if (fDir)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ // 情報を保存してカウントアップ。\r
+ this->fileinfo.Add(piInfo.fiInfo);\r
+ }\r
+ while (tpi.GetFileInformation(& piInfo.fiInfo));\r
+ }\r
+\r
+ // GetFileInformationがエラー終了した場合。\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));\r
+\r
+ // 書庫の情報を取得。\r
+ tpi.GetArchiveInformation(& this->aiArchive);\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));\r
+\r
+ // 書庫を閉じる。\r
+ tpi.CloseArchive();\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));\r
+\r
+ // 以下、UI処理。\r
+ this->fileinfo.Shrink();\r
+ this->tree_ctrl->ExpandAll();\r
+ this->tree_ctrl->ScrollTo(idArchive);\r
+ this->tree_ctrl->SelectItem(idArchive);\r
+ this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
+ this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));\r
+\r
+ // ステータスバー設定。\r
+ this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);\r
+ this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);\r
+ this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);\r
+ this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);\r
+ this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);\r
+\r
+ // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。\r
+ SetMenuToolState("Arc_Close", true);\r
+ SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);\r
+ SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);\r
+ SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);\r
+ SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);\r
+ SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);\r
+ SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);\r
+ this->menubar->Enable(XRCID("Arc_Clone"), true);\r
+\r
+ procDlg.Show(false);\r
+ this->Raise();\r
+}\r
+\r
+void MainFrame::OnArcClose(wxCommandEvent& e)\r
+{\r
+ // ツリービュー・リストビュー設定。\r
+ this->tree_ctrl->DeleteAllItems();\r
+ this->list_ctrl->DeleteAllItems();\r
+ this->list_ctrl->apShowFile.Clear();\r
+\r
+ // ツールバー・メニューバー設定。\r
+ SetMenuToolState("Arc_Close", false);\r
+ SetMenuToolState("Arc_Add", false);\r
+ SetMenuToolState("Arc_SFX", false);\r
+ SetMenuToolState("Arc_UnSFX", false);\r
+ SetMenuToolState("Arc_Extract", false);\r
+ SetMenuToolState("Arc_Delete", false);\r
+ SetMenuToolState("Arc_Test", false);\r
+ SetMenuToolState("Arc_Repair", false);\r
+ this->menubar->Enable(XRCID("Arc_Clone"), false);\r
+\r
+ for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)\r
+ {\r
+ this->statusbar->SetStatusText(wxEmptyString, i);\r
+ }\r
+ this->fileinfo.Clear();\r
+ this->aiArchive.szComment.Empty();\r
+ this->aiArchive.fnArchive.Clear();\r
+ this->aiArchive.fiInfo.szTypeName.Empty();\r
+ this->aiArchive.fiInfo.szSuffix.Empty();\r
+ this->aiArchive.fiInfo.szEngineName.Empty();\r
+ this->aiArchive.fiInfo.szTPIName.Empty();\r
+\r
+ g_hIconT.RemoveAll();\r
+ g_hIconLL.RemoveAll();\r
+ g_hIconLS.RemoveAll();\r
+\r
+ // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。\r
+ if (e.GetExtraLong() == 0)\r
+ {\r
+ tpi.FreeLibrary();\r
+ }\r
+}\r
+\r
+void MainFrame::OnArcClone(wxCommandEvent&)\r
+{\r
+ // 保存先を尋ねる。\r
+ wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
+ if (fd.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+ // コピー。\r
+ ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());\r
+ wxFileName fn(fd.GetPath());\r
+ wxDateTime dtAccess, dtModify, dtCreate;\r
+ this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);\r
+ fn.SetTimes(& dtAccess, & dtModify, & dtCreate);\r
+}\r
+\r
+void MainFrame::OnArcAdd(wxCommandEvent& e)\r
+{\r
+ // 作成ダイアログを設定。\r
+ MakeDialog mkDlg;\r
+ ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+ ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+ mkDlg.uCommand = TPI_COMMAND_ADD;\r
+\r
+ // 処理対象のファイルを選択。\r
+ wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
+ if (fd.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+ fd.GetFilenames(mkDlg.files);\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+ // ダイアログを表示。\r
+ if (mkDlg.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // 各種設定。\r
+ TPI_SWITCHES swInfo;\r
+ swInfo.pCustomSwitches = NULL;\r
+ swInfo.fMakeSFX = false;\r
+ swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());\r
+ swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
+ swInfo.fSolid = mkDlg.cbSolid->IsChecked();\r
+ swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();\r
+ swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();\r
+ swInfo.nCompressLevel = mkDlg.scLevel->GetValue();\r
+ swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();\r
+ swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
+ swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();\r
+ swInfo.szComment = mkDlg.tcComment->GetValue();\r
+\r
+ // 処理を行う。\r
+ {\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false);\r
+ }\r
+\r
+ if (mkDlg.cbOpenAfter->IsChecked())\r
+ {\r
+ // 作成先を開く。\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+ }\r
+\r
+ if (mkDlg.cbExitAfter->IsChecked())\r
+ {\r
+ // 終了。\r
+ this->Close(true);\r
+ }\r
+\r
+ // 終了しない場合は書庫を再読み込み。\r
+ this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcConvert(wxCommandEvent& e)\r
+{\r
+ TPI_SWITCHES swInfo;\r
+ swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");\r
+\r
+ // 保存先を尋ねる。\r
+ wxFileDialog fd(this, swInfo.fMakeSFX ? _("Save as SFX") : _("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
+ if (fd.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+ swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
+ this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+ wxArrayString files;\r
+ files.Add(fd.GetPath());\r
+\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+ tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false);\r
+}\r
+\r
+void MainFrame::OnArcExtract(wxCommandEvent& e)\r
+{\r
+ TPI_SWITCHES swInfo;\r
+ swInfo.pCustomSwitches = NULL;\r
+\r
+ // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。\r
+ int nMode = e.GetInt();\r
+ if (e.GetInt() == 8)\r
+ {\r
+ nMode = 0;\r
+ }\r
+ // 実行時のみ使用。\r
+ wxFileType * ftFile = NULL;\r
+\r
+ // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
+ MakeDialog mkDlg;\r
+ ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+ ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+ mkDlg.uCommand = TPI_COMMAND_EXTRACT;\r
+ mkDlg.files = MakeTargetFileList(this, nMode == 1);\r
+\r
+ if (nMode != 0)\r
+ {\r
+ // 作業ディレクトリ作成。\r
+ swInfo.fStoreDirectoryPathes = false;\r
+ wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
+ wxStandardPaths p;\r
+ if (szDestDirBase == wxT("-----"))\r
+ {\r
+ // 書庫ルートのときは書庫名にしておく。\r
+ szDestDirBase = this->fnArchive.GetName();\r
+ }\r
+ swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(p.GetTempDir()), szDestDirBase, true);\r
+ if (! swInfo.fnDestinationDirectory.IsOk())\r
+ {\r
+ wxLogError(_("Unable to make the temporary directory!"));\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (mkDlg.ShowModal() == wxID_CANCEL)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // 各種設定。\r
+ swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
+ swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());\r
+ swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
+ swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();\r
+\r
+ // 必要なら書庫名でディレクトリを作成する。\r
+ if (WillMakeDirByArcName(this, & mkDlg))\r
+ {\r
+ swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);\r
+ if (! swInfo.fnDestinationDirectory.IsOk())\r
+ {\r
+ wxLogError(_("Unable to make the destination directory!"));\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
+ // 処理を行う。\r
+ {\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false);\r
+ }\r
+\r
+ if (nMode == 0)\r
+ {\r
+ if (mkDlg.cbOpenAfter->IsChecked())\r
+ {\r
+ // 展開先を開く。\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+ }\r
+\r
+ if (mkDlg.cbExitAfter->IsChecked())\r
+ {\r
+ // 終了。\r
+ this->Close(true);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (nMode == 1)\r
+ {\r
+ // コマンドを取得。\r
+ ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());\r
+ if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())\r
+ {\r
+ // 種類が取得できないときはテキストとみなす。\r
+ ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
+ }\r
+\r
+ // コマンドを実行。\r
+ wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();\r
+ bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;\r
+ myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());\r
+ if (fSuccess)\r
+ {\r
+#ifdef __LINUX__\r
+ // Linuxでは引用符で囲む必要がある。\r
+ fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;\r
+#else\r
+ fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;\r
+#endif\r
+ }\r
+ if (! fSuccess)\r
+ {\r
+ pCallback->OnTerminate(0, 0);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // 展開対象を決定。\r
+ wxArrayString asFiles;\r
+ myFileDataObject * objFile = new myFileDataObject();\r
+ objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();\r
+ for (size_t i = 0; i < mkDlg.files.GetCount(); i++)\r
+ {\r
+ wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();\r
+ if (nMode == 3)\r
+ {\r
+ asFiles.Add(szFileName);\r
+ }\r
+ else\r
+ {\r
+ // リストに追加。\r
+ objFile->AddFile(szFileName);\r
+ }\r
+ }\r
+ if (nMode == 3)\r
+ {\r
+ objFile->AddFile(objFile->szTempDir);\r
+ }\r
+\r
+ if (nMode == 4)\r
+ {\r
+ wxTheClipboard->SetData(objFile);\r
+ }\r
+ else\r
+ {\r
+ // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。\r
+ this->SetDropTarget(NULL);\r
+\r
+ // DnD開始。\r
+ wxDropSource dropSource(* objFile, this);\r
+ wxDragResult drResult = dropSource.DoDragDrop();\r
+ if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)\r
+ {\r
+#ifdef __LINUX__\r
+ // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
+ sleep(3);\r
+#endif\r
+ }\r
+ this->SetDropTarget(new myFileDropTarget(this));\r
+\r
+ // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。\r
+ if (nMode == 3)\r
+ {\r
+ for (size_t i = 0; i < asFiles.GetCount(); i++)\r
+ {\r
+ chmod(asFiles[i].ToUTF8(), 0600);\r
+ ::wxRemoveFile(asFiles[i]);\r
+ }\r
+ }\r
+\r
+ delete objFile;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+void MainFrame::OnArcDelete(wxCommandEvent& e)\r
+{\r
+ // 全ファイル削除は危険ではないかと。\r
+ if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+ {\r
+ // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+ SetMenuToolState("Arc_Delete", false);\r
+ return;\r
+ }\r
+\r
+ if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // 処理を行う。\r
+ {\r
+ TPI_SWITCHES swInfo;\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false);\r
+ }\r
+\r
+ // 書庫を再読み込みする。\r
+ this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcTest(wxCommandEvent&)\r
+{\r
+ // 処理を行う。\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ TPI_SWITCHES swInfo;\r
+ bool bIsCorrect = tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+ procDlg.Show(false);\r
+\r
+ if (bIsCorrect)\r
+ {\r
+ wxLogMessage(_("This is a correct archive."));\r
+ }\r
+ else\r
+ {\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ }\r
+}\r
+\r
+void MainFrame::OnArcRepair(wxCommandEvent&)\r
+{\r
+ // 処理を行う。\r
+ ProcessDialog procDlg;\r
+ procDlg.Show(true);\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+ // コールバックを送信。\r
+ TPI_PROCESSINFO piInfo;\r
+ piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+ piInfo.eStatus = 0x1000;\r
+ piInfo.fiInfo.fnFileName = this->fnArchive;\r
+ piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+ procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ TPI_SWITCHES swInfo;\r
+ tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
+ procDlg.Show(false); \r
+}\r
+\r
+void MainFrame::OnExeCopy(wxCommandEvent & e)\r
+{\r
+ if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+ {\r
+ // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+ this->menubar->Enable(XRCID("Exe_Copy"), false);\r
+ return;\r
+ }\r
+\r
+ if (! wxTheClipboard->Open())\r
+ {\r
+ return;\r
+ }\r
+\r
+ e.SetInt(4);\r
+ this->OnArcExtract(e);\r
+ wxTheClipboard->Close();\r
+}\r
+\r
+void MainFrame::OnViewMode(wxCommandEvent & e)\r
+{\r
+ int n = e.GetId();\r
+ this->menubar->Check(n, true);\r
+ this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));\r
+ this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));\r
+ this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));\r
+}\r
+\r
+void MainFrame::OnShowToolBar(wxCommandEvent & e)\r
+{\r
+ this->toolbar->Show(e.IsChecked());\r
+}\r
+\r
+void MainFrame::OnShowStatusBar(wxCommandEvent & e)\r
+{\r
+ this->statusbar->Show(e.IsChecked());\r
+}\r
+\r
+void MainFrame::OnSelectAll(wxCommandEvent &)\r
+{\r
+ for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)\r
+ {\r
+ this->list_ctrl->Select(i, true);\r
+ }\r
+}\r
+\r
+// TreeView\r
+\r
+void MainFrame::OnTreeChanged(wxTreeEvent& e)\r
+{\r
+ // ツリービューからパスを取得。\r
+ wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
+ // リストビューを初期化。\r
+ this->list_ctrl->apShowFile.Clear();\r
+ this->list_ctrl->DeleteAllItems();\r
+ g_hIconLL.RemoveAll();\r
+ g_hIconLS.RemoveAll();\r
+\r
+ // 現在のアイテムの選択状態を無効にしておく。\r
+ long nSelected = this->list_ctrl->GetFirstSelected();\r
+ while (nSelected != -1)\r
+ {\r
+ this->list_ctrl->Select(nSelected, false);\r
+ nSelected = this->list_ctrl->GetNextSelected(nSelected);\r
+ }\r
+\r
+ // アイコン設定。\r
+ this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);\r
+ this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
+\r
+ // 配列と比較し、パスが一致しなければ消す。\r
+ for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
+ {\r
+ // パスを比較。\r
+ if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
+ {\r
+ // 項目がフォルダであるなら無視。\r
+ 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
+ {\r
+ continue;\r
+ }\r
+\r
+ // フィルタにかからなければ無視。\r
+ if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);\r
+ }\r
+ }\r
+\r
+ // ソートして表示。\r
+ this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);\r
+ this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());\r
+}\r
+\r
+void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)\r
+{\r
+ // TODO : アイテムが子階層を持っていても展開できない。\r
+ this->tree_ctrl->SelectItem(e.GetItem());\r
+\r
+ wxCommandEvent e1;\r
+ e1.SetInt(3);\r
+ this->OnArcExtract(e1);\r
+}\r
+\r
+void MainFrame::OnContextMenu(wxContextMenuEvent& e)\r
+{\r
+ wxPoint p = e.GetPosition();\r
+ this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));\r
+}\r
+\r
+// ListView\r
+\r
+void MainFrame::OnListItemSelect(wxListEvent&)\r
+{\r
+ // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。\r
+ bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;\r
+ SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);\r
+ this->menubar->Enable(XRCID("Exe_Copy"), fEnable);\r
+}\r
+\r
+void MainFrame::OnListItemDClick(wxListEvent&)\r
+{\r
+ wxCommandEvent e;\r
+ e.SetInt(1);\r
+ this->OnArcExtract(e);\r
+}\r
+\r
+void MainFrame::OnListBeginDrag(wxListEvent&)\r
+{\r
+ if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+ {\r
+ // アイテムを選択せずドラッグしようとした場合。\r
+ return;\r
+ }\r
+\r
+ wxCommandEvent e;\r
+ e.SetInt(2);\r
+ this->OnArcExtract(e);\r
+}\r
+\r
+// Filter\r
+\r
+void MainFrame::OnFilter(wxCommandEvent&)\r
+{\r
+ wxTreeEvent e;\r
+ e.SetItem(this->tree_ctrl->GetSelection());\r
+ this->OnTreeChanged(e);\r
+}\r
+\r
+// イベントハンドラ以外。\r
+\r
+bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)\r
+{\r
+ // 書庫を開いていれば閉じておく。\r
+ wxCommandEvent e;\r
+ this->OnArcClose(e);\r
+\r
+ // TPIを読み込み。\r
+ wxDir fs(L_DIR_B_LIB);\r
+ wxString szTPIName;\r
+ if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))\r
+ {\r
+ do\r
+ {\r
+ // 初期化。\r
+ if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName))\r
+ {\r
+ tpi.FreeLibrary();\r
+ continue;\r
+ }\r
+\r
+ // コールバック関数を設定。\r
+ tpi.SetCallbackProc(TPICallbackProc);\r
+\r
+ // 対応確認。\r
+ if (! tpi.OpenArchive(szFileName, llFileCount))\r
+ {\r
+ tpi.FreeLibrary();\r
+ * llFileCount = 0;\r
+ continue;\r
+ }\r
+ return true;\r
+ }\r
+ while (fs.GetNext(& szTPIName));\r
+ }\r
+ return false;\r
+}\r
+\r
+int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)\r
+{\r
+ switch (nErrorCode)\r
+ {\r
+ case TPI_ERROR_SUCCESS:\r
+ case TPI_ERROR_S_ENDOFDATA:\r
+ case TPI_CALLBACK_CONTINUE:\r
+ break;\r
+ case TPI_ERROR_D_UNSUPPORTED:\r
+ wxLogError(_("Sorry, this function is not supported yet."));\r
+ break;\r
+ case TPI_ERROR_D_SKIPPED:\r
+ case TPI_CALLBACK_CANCEL:\r
+ wxLogError(_("This operation is canceled by the user."));\r
+ break;\r
+ default:\r
+ wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);\r
+ }\r
+ return nErrorCode;\r
+}\r