OSDN Git Service

C++11のauto, nullptrを導入。
[tpi/lychee.git] / src / lychee / frm_main.cpp
index cbdcffc..3962438 100644 (file)
@@ -45,7 +45,7 @@ bool g_fSortAscend;
 // MainFrame\r
 //******************************************************************************\r
 \r
-MainFrame::MainFrame(): wxFrame()\r
+MainFrame::MainFrame(): wxFrame(), gFrame(nullptr)\r
 {\r
 }\r
 \r
@@ -62,7 +62,12 @@ MainFrame::~MainFrame()
                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
+       // ウインドウが表示されていないときは、GetSashPosition()が不正な値を返す。\r
+       if (this->IsShown())\r
+       {\r
+               this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());\r
+       }\r
 \r
        // ツールバー/ステータスバー関連。\r
        this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());\r
@@ -77,7 +82,7 @@ MainFrame::~MainFrame()
                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_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
@@ -88,6 +93,7 @@ MainFrame::~MainFrame()
        }\r
 \r
        wxCommandEvent e;\r
+       delete this->gFrame;\r
        this->Show(false);\r
        this->OnArcClose(e);\r
 }\r
@@ -97,7 +103,9 @@ MainFrame::~MainFrame()
 //******************************************************************************\r
 \r
 BEGIN_EVENT_TABLE(MainFrame, wxFrame)\r
-       EVT_INIT_DIALOG(      MainFrame::OnInit)\r
+       EVT_INIT_DIALOG(MainFrame::OnInit)\r
+       EVT_SIZE(       MainFrame::OnSize)\r
+       EVT_CLOSE(      MainFrame::OnClose)\r
        // Menu\r
        EVT_MENU(XRCID("Arc_Create"),  MainFrame::OnArcCreate)\r
        EVT_MENU(XRCID("Arc_Open"),    MainFrame::OnArcOpen)\r
@@ -194,6 +202,33 @@ void MainFrame::OnInit(wxInitDialogEvent&)
        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
+       this->gFrame = new wxGauge(this->statusbar, -1, 0, wxPoint(0, 0), wxSize(200, 10));\r
+       this->gFrame->Show(false);\r
+}\r
+\r
+void MainFrame::OnClose(wxCloseEvent& e)\r
+{\r
+       if (e.CanVeto() && g_procDlg != nullptr)\r
+       {\r
+               g_procDlg->OnClose(e);\r
+               e.Veto();\r
+       }\r
+       else\r
+       {\r
+               this->Destroy();\r
+       }\r
+}\r
+\r
+void MainFrame::OnSize(wxSizeEvent& e)\r
+{\r
+       // プログレスバーの位置を変更。\r
+       if (this->gFrame != nullptr)\r
+       {\r
+               this->gFrame->SetPosition(wxPoint(this->statusbar->GetSize().GetWidth() - 230, 10));\r
+       }\r
+       e.Skip();\r
 }\r
 \r
 // MenuBar\r
@@ -206,32 +241,49 @@ void MainFrame::OnExit(wxCommandEvent&)
 void MainFrame::OnArcCreate(wxCommandEvent& e)\r
 {\r
        TPI_SWITCHES swInfo;\r
-       swInfo.pCustomSwitches = NULL;\r
+       swInfo.pCustomSwitches = nullptr;\r
 \r
        // 作成ダイアログを設定。\r
        MakeDialog mkDlg(this, TPI_COMMAND_CREATE);\r
-       if (e.GetClientData() == NULL)\r
+       if (e.GetClientData() == nullptr)\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
+               if (::wxGetKeyState(WXK_SHIFT))\r
                {\r
-                       return;\r
+                       // 処理対象のフォルダを選択。\r
+                       wxDirDialog dd(this, _("Choose dir to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);\r
+                       if (dd.ShowModal() == wxID_CANCEL)\r
+                       {\r
+                               return;\r
+                       }\r
+                       swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());\r
+                       this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());\r
+                       mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());\r
+               }\r
+               else\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
+                       fd.GetFilenames(mkDlg.files);\r
+                       swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
+                       this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\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 (auto s : mkDlg.files)\r
                for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
                {\r
-                       wxFileName fn(mkDlg.files[n]);\r
+                       wxString & s = mkDlg.files[n];\r
+                       wxFileName fn(s);\r
                        fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
-                       mkDlg.files[n] = fn.GetFullPath();\r
+                       s = fn.GetFullPath();\r
                }\r
        }\r
 \r
@@ -252,7 +304,7 @@ void MainFrame::OnArcCreate(wxCommandEvent& e)
        int nSelected = mkDlg.chType->GetSelection();\r
        swInfo.nArchiveType         = mkDlg.afInfo[nSelected].nTypeId;\r
        swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();\r
-       swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->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
@@ -266,6 +318,7 @@ void MainFrame::OnArcCreate(wxCommandEvent& e)
 \r
        // TPIを読み込み。\r
        this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());\r
+       swInfo.szArcName            = this->fnArchive.GetFullPath();\r
        if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), TPICallbackProc, mkDlg.afInfo[nSelected].nTypeId))\r
        {\r
                this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));\r
@@ -275,12 +328,11 @@ void MainFrame::OnArcCreate(wxCommandEvent& e)
        // 処理を行う。\r
        {\r
                ProcessDialog procDlg(this, mkDlg.files.GetCount());\r
-               procDlg.Show(true);\r
-\r
-               tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               tpi.Command(TPI_COMMAND_CREATE, & swInfo, mkDlg.files);\r
                procDlg.Show(false);\r
                if (this->ErrorCheck(tpi.nErrorCode) != TPI_ERROR_SUCCESS)\r
                {\r
+                       tpi.FreeLibrary();\r
                        return;\r
                }\r
        }\r
@@ -301,6 +353,7 @@ void MainFrame::OnArcCreate(wxCommandEvent& e)
        // 終了しない場合は書庫を開く。\r
        if (this->fnArchive.FileExists())\r
        {\r
+               e.SetInt(1);\r
                this->OnArcOpen(e);\r
        }\r
 }\r
@@ -308,7 +361,7 @@ void MainFrame::OnArcCreate(wxCommandEvent& e)
 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
+       int nMode = e.GetInt();\r
 \r
        // 書庫を選択。\r
        if (nMode == 0)\r
@@ -322,16 +375,12 @@ void MainFrame::OnArcOpen(wxCommandEvent& e)
                this->fnArchive = wxFileName(fd.GetPath());\r
        }\r
 \r
-       // 進捗ダイアログ表示\r
+       // TPIを読み込み\r
        ProcessDialog procDlg(this);\r
-       procDlg.Show(true);\r
-\r
-       // DnD以外で書庫を開く場合、TPIを読み込み。\r
        TPI_PROCESSINFO piInfo;\r
        piInfo.fiInfo.nUnpackedSize = 0;\r
        if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))\r
        {\r
-               procDlg.Show(false);\r
                if (nMode == 2)\r
                {\r
                        // DnDの場合は書庫を作成する。\r
@@ -350,14 +399,20 @@ void MainFrame::OnArcOpen(wxCommandEvent& e)
                return;\r
        }\r
 \r
+       // コマンドラインから書庫を開く場合にはウインドウが表示されていないので表示。\r
+       if (! this->IsShown())\r
+       {\r
+               this->Show();\r
+       }\r
+\r
        piInfo.eMessage = TPI_MESSAGE_STATUS;\r
        piInfo.eStatus = 0x1001;\r
        if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)\r
        {\r
                procDlg.Show(false);\r
                tpi.CloseArchive();\r
-               wxCommandEvent e;\r
-               this->OnArcClose(e);\r
+               // OnArcClose処理はProcessDialogのデストラクタで行う。\r
+               // this->OnArcClose(e);\r
                return;\r
        }\r
 \r
@@ -379,7 +434,7 @@ void MainFrame::OnArcOpen(wxCommandEvent& e)
                idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);\r
 \r
        // 巨大書庫のときにファイル名検査を省略するか。\r
-       bool bDTVCheck = piInfo.fiInfo.nUnpackedSize < 10000 || ::AskDlg(_("This archive contains so many files that it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure this archive is safe, you can skip this scanning process. Do you want to scan for DTV problem?"), this) == wxNO;\r
+       bool bDTVCheck = true;//piInfo.fiInfo.nUnpackedSize < 10000 || AskDlg(_("This archive contains so many files that it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure this archive is safe, you can skip this scanning process. Do you want to scan for DTV problem?"), this) == wxNO;\r
 \r
        // ファイル情報をロード。\r
        if (tpi.GetFileInformation(& piInfo.fiInfo, true))\r
@@ -393,125 +448,131 @@ void MainFrame::OnArcOpen(wxCommandEvent& e)
                        {\r
                                procDlg.Show(false);\r
                                tpi.CloseArchive();\r
-                               wxCommandEvent e;\r
-                               this->OnArcClose(e);\r
+                               // OnArcClose処理はProcessDialogのデストラクタで行う。\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
+                       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
-                       // ルート記号を削除。\r
-                       wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);\r
-                       if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))\r
+//     for (auto f : this->fileinfo)\r
+       for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
+       {\r
+               TPI_FILEINFO & f = this->fileinfo[i];\r
+               // 拡張子のみ設定されている場合。\r
+               if (f.szStoredName.IsEmpty())\r
+               {\r
+                       f.szStoredName = this->fnArchive.GetName();\r
+                       if (f.fnFileName.HasExt())\r
                        {\r
-                               piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);\r
+                               f.szStoredName += wxT('.') + f.fnFileName.GetExt();\r
                        }\r
-                       // ルートメンバの情報は無視する。\r
-                       if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))\r
+                       f.fnFileName = wxFileName(f.szStoredName);\r
+               }\r
+\r
+               // セキュリティチェック。\r
+               // ルート記号を削除。\r
+               wxString szPath = f.fnFileName.GetPathWithSep(wxPATH_UNIX);\r
+               if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))\r
+               {\r
+                       f.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), f.fnFileName.GetFullName(), wxPATH_DOS);\r
+               }\r
+               // ルートメンバの情報は無視する。\r
+               if (f.fnFileName.GetFullPath().IsEmpty() || f.fnFileName.GetFullPath() == wxT("."))\r
+               {\r
+                       continue;\r
+               }\r
+\r
+               // 改行文字/タブ文字などを削除。\r
+               if (f.szStoredName.Find(wxT('\r')) != wxNOT_FOUND\r
+               ||  f.szStoredName.Find(wxT('\n')) != wxNOT_FOUND\r
+               ||  f.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)\r
+               {\r
+                       wxString sz = f.fnFileName.GetFullPath();\r
+                       sz.Replace(wxT("\r"), wxT(" "));\r
+                       sz.Replace(wxT("\n"), wxT(" "));\r
+                       sz.Replace(wxT("\t"), wxT(" "));\r
+                       f.eDanger = TRUE;\r
+                       f.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"), f.fnFileName.GetFullPath().c_str());\r
+               }\r
+\r
+               if (bDTVCheck)\r
+               {\r
+                       // DTV検査。\r
+                       if (f.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)\r
                        {\r
-                               continue;\r
+                               f.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"), f.fnFileName.GetFullPath().c_str());\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
+                       if (f.fnFileName.GetFullName().Find(wxT("        ")) != 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
+                               f.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"), f.fnFileName.GetFullPath().c_str());\r
                        }\r
-\r
-                       if (bDTVCheck)\r
+                       // Unicode制御文字を検査。\r
+                       for (wxChar c = 0x200c; c <= 0x206f; c++)\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
+                               if (f.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 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
+                                       f.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"), f.fnFileName.GetFullPath().c_str());\r
                                }\r
-                               // Unicode制御文字を検査。\r
-                               for (wxChar c = 0x200c; c <= 0x206f; c++)\r
+                               switch (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
+                               case 0x200f: c = 0x2027; break;\r
+                               case 0x202e: c = 0x2060; break;\r
                                }\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
+               bool fDir = f.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;\r
+               TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? f.fnFileName.GetFullPath() : f.fnFileName.GetPath(), true);\r
 \r
-                       // ディレクトリ属性を含むものについては情報を保存しない。\r
-                       if (fDir)\r
-                       {\r
-                               continue;\r
-                       }\r
-\r
-                       // 情報を保存してカウントアップ。\r
-                       this->fileinfo.Add(piInfo.fiInfo);\r
+               // ディレクトリ属性を含むものについては情報を保存しない。\r
+               if (fDir)\r
+               {\r
+                       continue;\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
        this->szPassword = procDlg.szPassword;\r
 \r
-       // 書庫を閉じる。\r
-       tpi.CloseArchive();\r
-       this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));\r
+       // Command()でハンドルを用いない場合は、ここで書庫を閉じる。\r
+       if (! tpi.bHandleOnCommand)\r
+       {\r
+               tpi.CloseArchive();\r
+               this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));\r
+       }\r
 \r
        // 以下、UI処理。\r
        this->fileinfo.Shrink();\r
-       this->tree_ctrl->Freeze();\r
-       if (this->fileinfo.Count() < 10000)\r
+//     if (this->fileinfo.Count() < 10000)\r
        {\r
                this->tree_ctrl->ExpandAll();\r
                this->tree_ctrl->SelectItem(idArchive);\r
        }\r
-       else\r
+/*     else\r
        {\r
                // ファイル数が多いとソートに時間がかかるので、書庫のルートを表示させる。\r
                this->tree_ctrl->Expand(idArcRoot);\r
                this->tree_ctrl->SelectItem(idArcRoot);\r
-       }\r
+       }*/\r
        // ツリービューの位置合わせ。\r
        this->tree_ctrl->ScrollTo(idArchive);\r
        this->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);\r
-       this->tree_ctrl->Thaw();\r
        this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
        this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));\r
 \r
@@ -535,20 +596,28 @@ void MainFrame::OnArcOpen(wxCommandEvent& e)
 \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_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_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
+       // タイトルバー設定。\r
+       this->SetTitle(this->fnArchive.GetFullName() + wxT(" - Lychee"));\r
+\r
        procDlg.Show(false);\r
        this->Raise();\r
 }\r
 \r
 void MainFrame::OnArcClose(wxCommandEvent& e)\r
 {\r
+       if (tpi.bHandleOnCommand)\r
+       {\r
+               tpi.CloseArchive();\r
+       }\r
+\r
        // ツリービュー・リストビュー設定。\r
        this->tree_ctrl->DeleteAllItems();\r
        this->list_ctrl->DeleteAllItems();\r
@@ -583,6 +652,9 @@ void MainFrame::OnArcClose(wxCommandEvent& e)
        g_hIconLL.RemoveAll();\r
        g_hIconLS.RemoveAll();\r
 \r
+       // タイトルバー設定。\r
+       this->SetTitle(wxT("Lychee"));\r
+\r
        // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。\r
        if (e.GetExtraLong() == 0)\r
        {\r
@@ -614,9 +686,9 @@ void MainFrame::OnArcAdd(wxCommandEvent& e)
        MakeDialog mkDlg(this, TPI_COMMAND_ADD);\r
 \r
        TPI_SWITCHES swInfo;\r
-       swInfo.pCustomSwitches       = NULL;\r
+       swInfo.pCustomSwitches       = nullptr;\r
 \r
-       if (e.GetClientData() == NULL)\r
+       if (e.GetClientData() == nullptr)\r
        {\r
                if (::wxGetKeyState(WXK_SHIFT))\r
                {\r
@@ -648,11 +720,13 @@ void MainFrame::OnArcAdd(wxCommandEvent& e)
                mkDlg.files = * (wxArrayString *) e.GetClientData();\r
                swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());\r
                // 相対パスに変換。\r
+//             for (auto s : mkDlg.files)\r
                for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
                {\r
-                       wxFileName fn(mkDlg.files[n]);\r
+                       wxString & s = mkDlg.files[n];\r
+                       wxFileName fn(s);\r
                        fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
-                       mkDlg.files[n] = fn.GetFullPath();\r
+                       s = fn.GetFullPath();\r
                }\r
        }\r
 \r
@@ -663,8 +737,9 @@ void MainFrame::OnArcAdd(wxCommandEvent& e)
        }\r
 \r
        // 各種設定。\r
-       swInfo.fMakeSFX              = false;\r
-       swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
+       swInfo.szArcName            = this->fnArchive.GetFullPath();\r
+       swInfo.fMakeSFX             = false;\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
@@ -677,9 +752,7 @@ void MainFrame::OnArcAdd(wxCommandEvent& e)
        // 処理を行う。\r
        {\r
                ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);\r
-               procDlg.Show(true);\r
-\r
-               tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               tpi.Command(TPI_COMMAND_ADD, & swInfo, mkDlg.files);\r
                this->ErrorCheck(tpi.nErrorCode);\r
                procDlg.Show(false);\r
        }\r
@@ -697,13 +770,15 @@ void MainFrame::OnArcAdd(wxCommandEvent& e)
        }\r
 \r
        // 終了しない場合は書庫を再読み込み。\r
+       e.SetInt(1);\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
+       swInfo.szArcName            = this->fnArchive.GetFullPath();\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
@@ -718,8 +793,7 @@ void MainFrame::OnArcConvert(wxCommandEvent& e)
        files.Add(fd.GetPath());\r
 \r
        ProcessDialog procDlg(this);\r
-       procDlg.Show(true);\r
-       tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);\r
+       tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, files);\r
        this->ErrorCheck(tpi.nErrorCode);\r
        procDlg.Show(false);\r
 }\r
@@ -727,8 +801,9 @@ void MainFrame::OnArcConvert(wxCommandEvent& e)
 void MainFrame::OnArcExtract(wxCommandEvent& e)\r
 {\r
        TPI_SWITCHES swInfo;\r
-       swInfo.pCustomSwitches = NULL;\r
-       swInfo.szPassword = this->szPassword;\r
+       swInfo.szArcName            = this->fnArchive.GetFullPath();\r
+       swInfo.pCustomSwitches      = nullptr;\r
+       swInfo.szPassword           = this->szPassword;\r
 \r
        // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。\r
        int nMode = e.GetInt();\r
@@ -737,7 +812,7 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
                nMode = 0;\r
        }\r
        // 実行時のみ使用。\r
-       wxFileType * ftFile = NULL;\r
+       wxFileType * ftFile = nullptr;\r
 \r
        // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
        MakeDialog mkDlg(this, TPI_COMMAND_EXTRACT);\r
@@ -790,9 +865,7 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
        // 処理を行う。\r
        {\r
                ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);\r
-               procDlg.Show(true);\r
-\r
-               tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, mkDlg.files);\r
                this->ErrorCheck(tpi.nErrorCode);\r
                procDlg.Show(false);\r
        }\r
@@ -833,13 +906,13 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
 \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
+                       bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != nullptr;\r
+                       auto 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
+                               fSuccess = ::wxExecute(wxT("xdg-open ") + QuoteString(szTempFile), wxEXEC_ASYNC, pCallback) > 0;\r
 #else\r
                                fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;\r
 #endif\r
@@ -853,11 +926,13 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
                {\r
                        // 展開対象を決定。\r
                        wxArrayString asFiles;\r
-                       myFileDataObject * objFile = new myFileDataObject();\r
+                       auto 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
+//                     for (auto s : mkDlg.files)\r
+                       for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
                        {\r
-                               wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();\r
+                               wxString & s = mkDlg.files[n];\r
+                               wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(s, wxPATH_DOS).GetFullName();\r
                                if (nMode == 3)\r
                                {\r
                                        asFiles.Add(szFileName);\r
@@ -880,7 +955,7 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
                        else\r
                        {\r
                                // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。\r
-                               this->SetDropTarget(NULL);\r
+                               this->SetDropTarget(nullptr);\r
 \r
                                // DnD開始。\r
                                wxDropSource dropSource(* objFile, this);\r
@@ -897,10 +972,12 @@ void MainFrame::OnArcExtract(wxCommandEvent& e)
                                // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。\r
                                if (nMode == 3)\r
                                {\r
+//                                     for (auto s : asFiles)\r
                                        for (size_t i = 0; i < asFiles.GetCount(); i++)\r
                                        {\r
-                                               chmod(asFiles[i].ToUTF8(), 0600);\r
-                                               ::wxRemoveFile(asFiles[i]);\r
+                                               wxString & s = asFiles[i];\r
+                                               chmod(s.ToUTF8(), 0600);\r
+                                               ::wxRemoveFile(s);\r
                                        }\r
                                }\r
 \r
@@ -920,7 +997,7 @@ void MainFrame::OnArcDelete(wxCommandEvent& e)
                return;\r
        }\r
 \r
-       if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
+       if (AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
        {\r
                return;\r
        }\r
@@ -929,16 +1006,16 @@ void MainFrame::OnArcDelete(wxCommandEvent& e)
        {\r
                wxArrayString asFiles = MakeTargetFileList(this);\r
                ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);\r
-               procDlg.Show(true);\r
-\r
                TPI_SWITCHES swInfo;\r
+               swInfo.szArcName  = this->fnArchive.GetFullPath();\r
                swInfo.szPassword = this->szPassword;\r
-               tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+               tpi.Command(TPI_COMMAND_DELETE, & swInfo, asFiles);\r
                this->ErrorCheck(tpi.nErrorCode);\r
                procDlg.Show(false);\r
        }\r
 \r
        // 書庫を再読み込みする。\r
+       e.SetInt(1);\r
        this->OnArcOpen(e);\r
 }\r
 \r
@@ -947,11 +1024,10 @@ void MainFrame::OnArcTest(wxCommandEvent&)
        // 処理を行う。\r
        wxArrayString asFiles = MakeTargetFileList(this);\r
        ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);\r
-       procDlg.Show(true);\r
-\r
        TPI_SWITCHES swInfo;\r
+       swInfo.szArcName  = this->fnArchive.GetFullPath();\r
        swInfo.szPassword = this->szPassword;\r
-       tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+       tpi.Command(TPI_COMMAND_TEST, & swInfo, asFiles);\r
        this->ErrorCheck(tpi.nErrorCode);\r
        procDlg.Show(false);\r
 }\r
@@ -961,11 +1037,10 @@ void MainFrame::OnArcRepair(wxCommandEvent&)
        // 処理を行う。\r
        wxArrayString asFiles = MakeTargetFileList(this);\r
        ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);\r
-       procDlg.Show(true);\r
-\r
        TPI_SWITCHES swInfo;\r
+       swInfo.szArcName  = this->fnArchive.GetFullPath();\r
        swInfo.szPassword = this->szPassword;\r
-       tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+       tpi.Command(TPI_COMMAND_REPAIR, & swInfo, asFiles);\r
        this->ErrorCheck(tpi.nErrorCode);\r
        procDlg.Show(false);    \r
 }\r
@@ -1041,24 +1116,26 @@ void MainFrame::OnTreeChanged(wxTreeEvent& e)
        this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
 \r
        // 配列と比較し、パスが一致しなければ消す。\r
+//     for (auto f : this->fileinfo)\r
        for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
        {\r
                // パスを比較。\r
-               if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
+               TPI_FILEINFO & f = this->fileinfo[i];\r
+               if (szNodePath == wxT("*") || szNodePath == f.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
+                       if (f.fnFileName.IsDir() || ! TreeView_CheckNewerItem(this->tree_ctrl, this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()), f.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
+                       if (f.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
+                       this->list_ctrl->apShowFile.Add(& f);\r
                }\r
        }\r
 \r
@@ -1137,15 +1214,8 @@ bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount
        {\r
                do\r
                {\r
-                       // 初期化。\r
-                       if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc))\r
-                       {\r
-                               tpi.FreeLibrary();\r
-                               continue;\r
-                       }\r
-\r
-                       // 対応確認。\r
-                       if (! tpi.OpenArchive(szFileName, llFileCount))\r
+                       // 初期化と対応確認。\r
+                       if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc) || ! tpi.OpenArchive(szFileName, llFileCount))\r
                        {\r
                                tpi.FreeLibrary();\r
                                * llFileCount = 0;\r