1 /*******************************************************************************
\r
2 TPI - flexible but useless plug-in framework.
\r
3 Copyright (C) 2002-2009 Silky
\r
5 This library is free software; you can redistribute it and/or modify it under
\r
6 the terms of the GNU Lesser General Public License as published by the Free
\r
7 Software Foundation; either version 2.1 of the License, or (at your option)
\r
10 This library is distributed in the hope that it will be useful, but WITHOUT
\r
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
\r
15 You should have received a copy of the GNU Lesser General Public License along
\r
16 with this library; if not, write to the Free Software Foundation, Inc.,
\r
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
\r
20 *******************************************************************************/
\r
24 #include "dlg_make.h"
\r
25 #include "frm_main.h"
\r
26 #include "functions.h"
\r
28 #include <wx/dirdlg.h>
\r
29 #include <wx/arrimpl.cpp>
\r
31 WX_DEFINE_OBJARRAY(ArrayTPI_FORMATINFO);
\r
33 //******************************************************************************
\r
35 //******************************************************************************
\r
37 MakeDialog::MakeDialog(): wxDialog()
\r
39 this->bIsMake = true;
\r
42 //******************************************************************************
\r
44 //******************************************************************************
\r
46 BEGIN_EVENT_TABLE(MakeDialog, wxDialog)
\r
47 EVT_INIT_DIALOG( MakeDialog::OnInit)
\r
48 EVT_BUTTON(XRCID("btnDefault"), MakeDialog::OnBtnDefault)
\r
49 EVT_BUTTON(XRCID("btnDesktop"), MakeDialog::OnBtnDesktop)
\r
50 EVT_BUTTON(XRCID("btnCurrent"), MakeDialog::OnBtnCurrent)
\r
51 EVT_BUTTON(XRCID("btnBrowse"), MakeDialog::OnBtnBrowse)
\r
52 EVT_BUTTON(XRCID("btnBrowseKF"), MakeDialog::OnBtnBrowseKF)
\r
53 EVT_BUTTON(XRCID("btnOK"), MakeDialog::OnBtnOK)
\r
54 EVT_BUTTON(XRCID("btnCancel"), MakeDialog::OnBtnCancel)
\r
55 EVT_CHOICE(XRCID("chType"), MakeDialog::OnChoice)
\r
56 EVT_CHECKBOX(XRCID("cbUnmask"), MakeDialog::OnCbUnmask)
\r
57 EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbTabs"), MakeDialog::OnTabChanged)
\r
60 //******************************************************************************
\r
62 //******************************************************************************
\r
64 void MakeDialog::OnInit(wxInitDialogEvent&)
\r
68 this->cbDir = XRCCTRL(* this, "cbDir", wxComboBox);
\r
69 this->cbFileName = XRCCTRL(* this, "cbFileName", wxComboBox);
\r
70 this->cbOpenAfter = XRCCTRL(* this, "cbOpenAfter", wxCheckBox);
\r
71 this->cbIgnorePath = XRCCTRL(* this, "cbIgnorePath", wxCheckBox);
\r
72 this->cbExitAfter = XRCCTRL(* this, "cbExitAfter", wxCheckBox);
\r
73 this->chType = XRCCTRL(* this, "chType", wxChoice);
\r
74 this->chDirMake = XRCCTRL(* this, "chDirMake", wxChoice);
\r
76 this->scLevel = XRCCTRL(* this, "scLevel", wxSpinCtrl);
\r
77 this->scRR = XRCCTRL(* this, "scRR", wxSpinCtrl);
\r
78 this->tcPassword = XRCCTRL(* this, "tcPassword", wxTextCtrl);
\r
79 this->tcKeyfile = XRCCTRL(* this, "tcKeyfile", wxTextCtrl);
\r
80 this->cbSplitSize = XRCCTRL(* this, "cbSplitSize", wxComboBox);
\r
81 this->cbUnmask = XRCCTRL(* this, "cbUnmask", wxCheckBox);
\r
82 this->cbEncryptHeader = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);
\r
83 this->cbSolid = XRCCTRL(* this, "cbSolid", wxCheckBox);
\r
84 this->cbMMOptimize = XRCCTRL(* this, "cbMMOptimize", wxCheckBox);
\r
85 this->cbMakeSFX = XRCCTRL(* this, "cbMakeSFX", wxCheckBox);
\r
87 this->tcComment = XRCCTRL(* this, "tcComment", wxTextCtrl);
\r
89 this->lcFiles = XRCCTRL(* this, "lcFiles", wxListCtrl);
\r
92 if (! this->cbDir->GetValue().IsEmpty())
\r
98 this->lcFiles->InsertColumn(0, _("Input"), wxLIST_FORMAT_LEFT, 150);
\r
99 this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT, 300);
\r
101 ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
104 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
105 wxString szArcPath = frm_main->fnArchive.GetPath(), szArcName = frm_main->fnArchive.GetName();
\r
107 // 展開時は各種コントロールの状態を変更する。
\r
108 if (! this->bIsMake)
\r
110 this->cbFileName->Disable();
\r
111 this->chType->Disable();
\r
112 this->chDirMake->Enable();
\r
113 this->scLevel->Disable();
\r
114 this->scRR->Disable();
\r
115 this->cbSplitSize->Disable();
\r
116 this->cbEncryptHeader->Disable();
\r
117 this->cbSolid->Disable();
\r
118 this->cbMMOptimize->Disable();
\r
119 this->cbMakeSFX->Disable();
\r
120 this->tcComment->SetEditable(false);
\r
123 this->tcComment->SetValue(frm_main->szComment);
\r
125 // 展開先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
126 if (this->files.GetCount() < 3000 || ::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) == wxYES)
\r
129 e.SetSelection(-3);
\r
130 this->OnTabChanged(e);
\r
135 wxArrayString asPath, asName;
\r
136 asPath.Add(szArcPath);
\r
137 asName.Add(szArcName);
\r
138 for (int i = 0; i < frm_main->conf.Read(wxT("LastUsed-Count"), 7); i++)
\r
140 wxFileName fnLastOpen(frm_main->conf.Read(wxString::Format(wxT("LastUsed%d"), i), wxEmptyString));
\r
141 if (! fnLastOpen.IsOk())
\r
146 wxString szPath = fnLastOpen.GetPath(), szName = fnLastOpen.GetName();
\r
147 if (! szPath.IsEmpty() && asPath.Index(szPath) == wxNOT_FOUND)
\r
149 asPath.Add(szPath);
\r
150 this->cbDir->Append(szPath);
\r
152 if (! szName.IsEmpty() && asName.Index(szName) == wxNOT_FOUND)
\r
154 asName.Add(szName);
\r
155 this->cbFileName->Append(szName);
\r
160 this->cbDir->SetValue(szArcPath);
\r
161 this->cbFileName->SetValue(szArcName);
\r
163 if (! this->bIsMake)
\r
172 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
173 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
174 while (! szTPIName.IsEmpty())
\r
177 if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))
\r
180 TPI_FORMATINFO fiInfo;
\r
181 if (tpi.GetFormatInformation(& fiInfo, true))
\r
185 if (fiInfo.llSupportedCommand & TPI_COMMAND_ADD && (this->files.GetCount() == 1 || fiInfo.fArchive))
\r
187 fiInfo.szTPIName = szTPIName;
\r
188 this->afInfo.Add(fiInfo);
\r
189 this->chType->Append(fiInfo.szTypeName);
\r
192 while (tpi.GetFormatInformation(& fiInfo, false));
\r
196 szTPIName = fs.FindNext();
\r
199 // とりあえず最初の形式にしておく。
\r
200 this->chType->SetSelection(0);
\r
206 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
208 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.Read(wxT("DefaultPath"), wxEmptyString));
\r
211 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
213 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
214 this->cbDir->SetValue(fn.GetFullPath());
\r
217 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
219 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
222 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
224 wxDirDialog dd(this);
\r
225 dd.SetPath(this->cbDir->GetValue());
\r
226 if (dd.ShowModal() == wxID_OK)
\r
228 this->cbDir->SetValue(dd.GetPath());
\r
232 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
234 wxFileDialog fd(this);
\r
235 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
236 if (fd.ShowModal() == wxID_OK)
\r
238 this->tcKeyfile->SetValue(fd.GetPath());
\r
242 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
245 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
246 wxFileName fnCurrent(this->cbDir->GetValue(), this->bIsMake ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
247 wxArrayString asLastUsed;
\r
248 asLastUsed.Add(fnCurrent.GetFullPath());
\r
249 for (int i = 0; i < frm_main->conf.Read(wxT("LastUsed-Count"), 7); i++)
\r
251 wxString szPath = frm_main->conf.Read(wxString::Format(wxT("LastUsed%d"), i), wxEmptyString);
\r
252 if (! szPath.IsEmpty() && asLastUsed.Index(szPath) == wxNOT_FOUND)
\r
254 asLastUsed.Add(szPath);
\r
257 for (size_t i = 0; i < asLastUsed.GetCount(); i++)
\r
259 frm_main->conf.Write(wxString::Format(wxT("LastUsed%d"), i), asLastUsed[i]);
\r
262 this->EndModal(wxID_OK);
\r
265 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
267 this->EndModal(wxID_CANCEL);
\r
270 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
272 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
273 // 形式が各種設定に対応しているか。
\r
274 this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
\r
275 this->scLevel->SetValue(fiInfo->sCompressLevelMax);
\r
276 this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
\r
277 this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
\r
278 this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
\r
279 this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
\r
280 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
281 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
282 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
283 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
284 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
285 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
286 this->cbSolid->Enable(fiInfo->fSolid);
\r
287 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
288 this->tcComment->Enable(fiInfo->fComment);
\r
291 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
293 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
294 this->tcPassword->Refresh();
\r
297 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
299 // "Files"タブのときは処理。
\r
300 bool bReallyShow = e.GetSelection() == 3;
\r
301 if (abs(e.GetSelection()) != 3)
\r
306 // "Files"タブを表示する初回かどうか。
\r
307 if (bReallyShow && this->lcFiles->GetItemCount() == 0)
\r
310 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
312 this->lcFiles->InsertItem(i, this->files[i]);
\r
319 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
323 this->lcFiles->SetItem(i, 1, this->files[i]);
\r
330 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
333 bool fDTVWarning = false;
\r
334 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
336 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
337 wxFileName fnStored(this->files[i]);
\r
338 if (! this->cbIgnorePath->IsChecked())
\r
340 szOutputFile += fnStored.GetPathWithSep();
\r
342 szOutputFile += fnStored.GetFullName();
\r
343 wxFileName fnOutput(szOutputFile);
\r
344 if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
346 fDTVWarning = true;
\r
349 this->lcFiles->SetItemTextColour(i, * wxRED);
\r
354 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
\r
358 if (fDTVWarning && ::AskDlg(_("This archive may have Directory Traversal Vulnerability(DTV) problem, and some danger files may be extracted to the unexpected system directory! It is strongly recommended to ignore file path. Would you like to do so?"), this) == wxYES)
\r
360 this->cbIgnorePath->SetValue(true);
\r
363 this->OnTabChanged(e);
\r