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
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("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
// 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_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)\r
- EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)\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
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
if (e.GetClientData() == NULL)\r
{\r
// 処理対象のファイルを選択。\r
- wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\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
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
- wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));\r
return;\r
}\r
\r
// コールバック関数を設定。\r
- if (! tpi.SetCallbackProc(TPICallbackProc))\r
- {\r
- wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));\r
- }\r
+ tpi.SetCallbackProc(TPICallbackProc);\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("SetCallbackProc"));\r
\r
// 処理を行う。\r
{\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = mkDlg.files.GetCount();\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
- if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
- {\r
- this->ErrorCheck(tpi.nErrorCode);\r
- return;\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
if (mkDlg.cbOpenAfter->IsChecked())\r
{\r
// 作成先を開く。\r
- ::wxExecute(DIR_APP + swInfo.fnDestinationDirectory.GetFullPath());\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
}\r
\r
if (mkDlg.cbExitAfter->IsChecked())\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 (e.GetId() == XRCID("Arc_Open"))\r
+ if (nMode == 0)\r
{\r
- wxFileDialog fd(this);\r
- fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);\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
this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
this->fnArchive = wxFileName(fd.GetPath());\r
}\r
- this->OnArcClose(e);\r
\r
// 進捗ダイアログ表示。\r
ProcessDialog procDlg;\r
- procDlg.Show(true);\r
+ procDlg.fnArchive = & this->fnArchive;\r
\r
- // TPIを読み込み、最初のコールバックを送信。\r
+ // DnD以外で書庫を開く場合、TPIを読み込み。\r
TPI_PROCESSINFO piInfo;\r
- piInfo.eMessage = TPI_MESSAGE_STATUS;\r
- piInfo.eStatus = 0x1000;\r
- piInfo.nProcessedSize = 0;\r
- piInfo.fiInfo.fnFileName = this->fnArchive;\r
- piInfo.fiInfo.nUnpackedSize = e.GetExtraLong() != 0 ? e.GetExtraLong() : this->LoadTPI(this->fnArchive.GetFullPath());\r
- if (piInfo.fiInfo.nUnpackedSize == 0)\r
+ if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))\r
{\r
- procDlg.Show(false);\r
tpi.FreeLibrary();\r
- wxLogError(_("No plug-in supporting this archive was found!"));\r
+ if (nMode == 2)\r
+ {\r
+ // DnDの場合は書庫を作成する。\r
+ this->OnArcCreate(e);\r
+ }\r
+ else 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
- procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+ procDlg.nFileCount = piInfo.fiInfo.nUnpackedSize;\r
+ procDlg.Show(true);\r
\r
// 配列のサイズを確保。\r
this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);\r
\r
- // 書庫を開く。\r
- if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))\r
- {\r
- procDlg.Show(false);\r
- tpi.FreeLibrary();\r
- wxLogError(_("Error: %s!"), wxT("OpenArchive()"));\r
- return;\r
- }\r
-\r
// 履歴に追加。\r
this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());\r
this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());\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
+ idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.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
+ idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.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.eMessage = TPI_MESSAGE_STATUS;\r
piInfo.eStatus = 0x1001;\r
+ piInfo.nProcessedSize = 0;\r
do\r
{\r
piInfo.nProcessedSize++;\r
- if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)\r
+ if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)\r
{\r
procDlg.Show(false);\r
tpi.CloseArchive();\r
return;\r
}\r
\r
- // ツリービューに反映。\r
- TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);\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
- if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)\r
+ // セキュリティチェック。\r
+ // ルート記号を削除。\r
+ wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);\r
+ if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))\r
+ {\r
+ piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);\r
+ }\r
+ // ルートメンバの情報は無視する。\r
+ if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))\r
{\r
continue;\r
}\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().Find(wxT("..")) != wxNOT_FOUND)\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
\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, false));\r
+ while (tpi.GetFileInformation(& piInfo.fiInfo));\r
}\r
\r
// GetFileInformationがエラー終了した場合。\r
- if (tpi.nErrorCode != TPI_ERROR_S_ENDOFDATA)\r
- {\r
- wxLogError(_("Error: %s!"), wxT("GetFileInformation()"));\r
- }\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));\r
\r
// 書庫の情報を取得。\r
- if (! tpi.GetArchiveInformation(& this->aiArchive))\r
- {\r
- wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));\r
- }\r
+ tpi.GetArchiveInformation(& this->aiArchive);\r
+ this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));\r
\r
// 書庫を閉じる。\r
- if (! tpi.CloseArchive())\r
- {\r
- wxLogError(_("Error: %s!"), wxT("CloseArchive()"));\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->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);\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(_("%d file(s)"), this->fileinfo.GetCount()), 1);\r
- this->statusbar->SetStatusText(wxString::Format(_("%dB -> %dB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);\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
+ // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。\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_Delete", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);\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
this->tree_ctrl->DeleteAllItems();\r
this->list_ctrl->DeleteAllItems();\r
- this->list_ctrl->showFileInfo.Clear();\r
+ this->list_ctrl->apShowFile.Clear();\r
\r
// ツールバー・メニューバー設定。\r
SetMenuToolState("Arc_Close", 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
// DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。\r
if (e.GetExtraLong() == 0)\r
{\r
- this->tpi.FreeLibrary();\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
mkDlg.uCommand = TPI_COMMAND_ADD;\r
\r
// 処理対象のファイルを選択。\r
- wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
- fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\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
{\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = mkDlg.files.GetCount();\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
- if (! tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
- {\r
- this->ErrorCheck(tpi.nErrorCode);\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 + swInfo.fnDestinationDirectory.GetFullPath());\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
}\r
\r
if (mkDlg.cbExitAfter->IsChecked())\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));\r
- fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\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
ProcessDialog procDlg;\r
procDlg.Show(true);\r
- if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))\r
- {\r
- this->ErrorCheck(tpi.nErrorCode);\r
- }\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
TPI_SWITCHES swInfo;\r
swInfo.pCustomSwitches = NULL;\r
\r
- // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。\r
+ // ã\83¢ã\83¼ã\83\89å\8f\96å¾\97ã\80\82é\80\9a常ã\81¯0, å®\9fè¡\8cã\81ªã\82\891, ã\83\95ã\82¡ã\82¤ã\83«DnDã\81ªã\82\892ã\80\81ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªDnDã\81ªã\82\893ã\80\81ã\82¯ã\83ªã\83\83ã\83\97ã\83\9cã\83¼ã\83\89ã\81ªã\82\894ã\80\81ã\82³ã\83³ã\83\86ã\82ã\82¹ã\83\88ã\83¡ã\83\8bã\83¥ã\83¼ã\81\8bã\82\89ã\81ªã\82\898ã\80\82\r
int nMode = e.GetInt();\r
+ if (e.GetInt() == 8)\r
+ {\r
+ nMode = 0;\r
+ }\r
// 実行時のみ使用。\r
wxFileType * ftFile = NULL;\r
\r
\r
if (nMode != 0)\r
{\r
- if (nMode == 1)\r
- {\r
- // コマンドを取得。\r
- ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());\r
- if (! ftFile)\r
- {\r
- // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。\r
- ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
- if (! ftFile)\r
- {\r
- wxLogError(_("Unable to get the file type!"));\r
- return;\r
- }\r
- }\r
- }\r
-\r
// 作業ディレクトリ作成。\r
swInfo.fStoreDirectoryPathes = false;\r
wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
// 処理を行う。\r
{\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = mkDlg.files.GetCount();\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
- if (! tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
- {\r
- this->ErrorCheck(tpi.nErrorCode);\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 (mkDlg.cbOpenAfter->IsChecked())\r
{\r
// 展開先を開く。\r
- ::wxExecute(DIR_APP + swInfo.fnDestinationDirectory.GetFullPath());\r
+ ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
}\r
\r
if (mkDlg.cbExitAfter->IsChecked())\r
}\r
else\r
{\r
- wxArrayString asFiles;\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
- asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName());\r
- if (tpi.nErrorCode == TPI_ERROR_SUCCESS)\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
- ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);\r
+ fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;\r
#else\r
- ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);\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
- // 展開対象を決定。wxGTKのwxFileDataObjectでは多バイト文字の扱いに問題があるので代替。\r
-#ifdef __LINUX__\r
- myFileDataObject objFile;\r
-#else\r
- wxFileDataObject objFile;\r
-#endif\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 == 2)\r
+ if (nMode == 3)\r
+ {\r
+ asFiles.Add(szFileName);\r
+ }\r
+ else\r
{\r
// リストに追加。\r
- objFile.AddFile(szFileName);\r
+ objFile->AddFile(szFileName);\r
}\r
- asFiles.Add(szFileName);\r
}\r
if (nMode == 3)\r
{\r
- objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());\r
+ objFile->AddFile(objFile->szTempDir);\r
}\r
\r
- // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。\r
- this->SetDropTarget(NULL);\r
-\r
- // DnD開始。\r
- wxDropSource dropSource(objFile, this);\r
- wxDragResult drResult = dropSource.DoDragDrop(wxDrag_DefaultMove);\r
- if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)\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
+ // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
+ sleep(3);\r
#endif\r
- }\r
- this->SetDropTarget(new myFileDropTarget(this));\r
- }\r
+ }\r
+ this->SetDropTarget(new myFileDropTarget(this));\r
\r
- // ファイルと一時ディレクトリを削除。\r
- for (size_t i = 0; i < asFiles.GetCount(); i++)\r
- {\r
- ::wxRemoveFile(asFiles[i]);\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
- ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());\r
}\r
}\r
\r
// 全ファイル削除は危険ではないかと。\r
if (this->list_ctrl->GetSelectedItemCount() == 0)\r
{\r
+ // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+ SetMenuToolState("Arc_Delete", false);\r
return;\r
}\r
\r
\r
// 処理を行う。\r
{\r
- TPI_SWITCHES swInfo;\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = asFiles.GetCount();\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
- if (! tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles))\r
- {\r
- this->ErrorCheck(tpi.nErrorCode);\r
- }\r
+ TPI_SWITCHES swInfo;\r
+ tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+ this->ErrorCheck(tpi.nErrorCode);\r
procDlg.Show(false);\r
}\r
\r
void MainFrame::OnArcTest(wxCommandEvent&)\r
{\r
// 処理を行う。\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = asFiles.GetCount();\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
void MainFrame::OnArcRepair(wxCommandEvent&)\r
{\r
// 処理を行う。\r
+ wxArrayString asFiles = MakeTargetFileList(this, false);\r
ProcessDialog procDlg;\r
+ procDlg.fnArchive = & this->fnArchive;\r
+ procDlg.nFileCount = asFiles.GetCount();\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
- if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles))\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
- this->ErrorCheck(tpi.nErrorCode);\r
+ // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+ this->menubar->Enable(XRCID("Exe_Copy"), false);\r
+ return;\r
}\r
- procDlg.Show(false); \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
wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
// リストビューを初期化。\r
- this->list_ctrl->showFileInfo.Clear();\r
+ this->list_ctrl->apShowFile.Clear();\r
this->list_ctrl->DeleteAllItems();\r
g_hIconLL.RemoveAll();\r
g_hIconLS.RemoveAll();\r
continue;\r
}\r
\r
- this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);\r
+ this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);\r
}\r
}\r
\r
// ソートして表示。\r
- this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);\r
- this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());\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
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
\r
// イベントハンドラ以外。\r
\r
-wxULongLong_t MainFrame::LoadTPI(wxString szFileName)\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
- wxULongLong_t llFileCount = 0;\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, 0))\r
+ if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName))\r
{\r
tpi.FreeLibrary();\r
continue;\r
tpi.SetCallbackProc(TPICallbackProc);\r
\r
// 対応確認。\r
- if (! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)\r
+ if (! tpi.OpenArchive(szFileName, llFileCount))\r
{\r
tpi.FreeLibrary();\r
- llFileCount = 0;\r
+ * llFileCount = 0;\r
continue;\r
}\r
- break;\r
+ return true;\r
}\r
while (fs.GetNext(& szTPIName));\r
}\r
- return llFileCount;\r
+ return false;\r
}\r
\r
-int MainFrame::ErrorCheck(int nErrorCode)\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(_("This operation is canceled by the user."));\r
break;\r
default:\r
- wxLogError(_("Error code: %d"), nErrorCode);\r
+ wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);\r
}\r
return nErrorCode;\r
}\r