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->uCommand = TPI_COMMAND_CREATE;
\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_CHECKBOX(XRCID("cbMakeSFX"), MakeDialog::OnCbMakeSFX)
\r
58 EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbTabs"), MakeDialog::OnTabChanged)
\r
61 //******************************************************************************
\r
63 //******************************************************************************
\r
65 void MakeDialog::OnInit(wxInitDialogEvent&)
\r
69 this->cbDir = XRCCTRL(* this, "cbDir", wxComboBox);
\r
70 this->cbFileName = XRCCTRL(* this, "cbFileName", wxComboBox);
\r
71 this->cbOpenAfter = XRCCTRL(* this, "cbOpenAfter", wxCheckBox);
\r
72 this->cbIgnorePath = XRCCTRL(* this, "cbIgnorePath", wxCheckBox);
\r
73 this->cbExitAfter = XRCCTRL(* this, "cbExitAfter", wxCheckBox);
\r
74 this->chType = XRCCTRL(* this, "chType", wxChoice);
\r
75 this->chDirMake = XRCCTRL(* this, "chDirMake", wxChoice);
\r
77 this->scLevel = XRCCTRL(* this, "scLevel", wxSpinCtrl);
\r
78 this->scRR = XRCCTRL(* this, "scRR", wxSpinCtrl);
\r
79 this->tcPassword = XRCCTRL(* this, "tcPassword", wxTextCtrl);
\r
80 this->tcKeyfile = XRCCTRL(* this, "tcKeyfile", wxTextCtrl);
\r
81 this->cbSplitSize = XRCCTRL(* this, "cbSplitSize", wxComboBox);
\r
82 this->cbUnmask = XRCCTRL(* this, "cbUnmask", wxCheckBox);
\r
83 this->cbEncryptHeader = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);
\r
84 this->cbSolid = XRCCTRL(* this, "cbSolid", wxCheckBox);
\r
85 this->cbMMOptimize = XRCCTRL(* this, "cbMMOptimize", wxCheckBox);
\r
86 this->cbMakeSFX = XRCCTRL(* this, "cbMakeSFX", wxCheckBox);
\r
88 this->tcComment = XRCCTRL(* this, "tcComment", wxTextCtrl);
\r
90 this->lcFiles = XRCCTRL(* this, "lcFiles", wxListCtrl);
\r
93 if (! this->cbDir->GetValue().IsEmpty())
\r
99 this->lcFiles->InsertColumn(0, _("Input"), wxLIST_FORMAT_LEFT, 150);
\r
100 this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT, 300);
\r
102 ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
105 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
106 wxString szArcPath = frm_main->fnArchive.GetPath(), szArcName = frm_main->fnArchive.GetName();
\r
109 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)
\r
111 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_PATH, i);
\r
117 this->cbDir->Append(sz);
\r
120 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)
\r
122 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_NAME, i);
\r
128 this->cbFileName->Append(sz);
\r
132 this->cbDir->SetValue(szArcPath);
\r
135 switch (this->uCommand)
\r
137 case TPI_COMMAND_EXTRACT:
\r
139 this->SetTitle(_("Extract"));
\r
140 this->tcComment->SetValue(frm_main->aiArchive.szComment);
\r
142 // 展開先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
143 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
146 e.SetSelection(-3);
\r
147 this->OnTabChanged(e);
\r
151 this->scLevel->Disable();
\r
152 this->scRR->Disable();
\r
153 this->cbEncryptHeader->Disable();
\r
154 this->cbSolid->Disable();
\r
155 this->cbMMOptimize->Disable();
\r
156 this->tcComment->SetEditable(false);
\r
157 case TPI_COMMAND_ADD:
\r
158 // コントロールを無効化(展開時も)。
\r
159 this->cbFileName->Disable();
\r
160 this->chType->Disable();
\r
161 this->chDirMake->Enable();
\r
162 this->cbSplitSize->Disable();
\r
163 this->cbMakeSFX->Disable();
\r
166 this->cbFileName->SetValue(szArcName);
\r
169 this->afInfo.Add(frm_main->aiArchive.fiInfo);
\r
170 this->chType->Append(frm_main->aiArchive.fiInfo.szTypeName);
\r
172 // とりあえず最初の形式にしておく。
\r
173 this->chType->SetSelection(0);
\r
180 if (this->uCommand != TPI_COMMAND_ADD)
\r
184 this->SetTitle(_("Add"));
\r
186 // コントロールを無効化(追加時のみ)。
\r
187 this->cbDir->Disable();
\r
188 this->chDirMake->Disable();
\r
190 case TPI_COMMAND_CREATE:
\r
191 this->SetTitle(_("Create"));
\r
193 // 書庫名を設定。初期化の都合上.を付加しておく。
\r
194 this->cbFileName->SetValue(szArcName + wxT('.'));
\r
199 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
200 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
201 while (! szTPIName.IsEmpty())
\r
204 if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))
\r
207 TPI_FORMATINFO fiInfo;
\r
208 if (tpi.GetFormatInformation(& fiInfo, true))
\r
212 if (fiInfo.llSupportedCommand & TPI_COMMAND_CREATE && (this->files.GetCount() == 1 || fiInfo.fArchive))
\r
214 fiInfo.szTPIName = szTPIName;
\r
215 this->afInfo.Add(fiInfo);
\r
216 this->chType->Append(fiInfo.szTypeName);
\r
219 while (tpi.GetFormatInformation(& fiInfo, false));
\r
223 szTPIName = fs.FindNext();
\r
226 if (this->chType->GetCount() == 0)
\r
229 XRCCTRL(* this, "btnOK", wxButton)->Disable();
\r
233 // とりあえず最初の形式にしておく。
\r
234 this->chType->SetSelection(0);
\r
242 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
244 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
247 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
249 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
250 this->cbDir->SetValue(fn.GetFullPath());
\r
253 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
255 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
258 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
260 wxDirDialog dd(this);
\r
261 dd.SetPath(this->cbDir->GetValue());
\r
262 if (dd.ShowModal() == wxID_OK)
\r
264 this->cbDir->SetValue(dd.GetPath());
\r
268 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
270 wxFileDialog fd(this);
\r
271 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
272 if (fd.ShowModal() == wxID_OK)
\r
274 this->tcKeyfile->SetValue(fd.GetPath());
\r
278 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
281 if (this->uCommand != TPI_COMMAND_ADD)
\r
283 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
284 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
285 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
286 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
287 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
289 this->EndModal(wxID_OK);
\r
292 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
294 this->EndModal(wxID_CANCEL);
\r
297 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
299 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
300 // 形式が各種設定に対応しているか。
\r
302 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
303 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
304 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
305 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
311 this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
\r
312 this->scLevel->SetValue(fiInfo->sCompressLevelMax);
\r
313 this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
\r
314 this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
\r
315 this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
\r
316 this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
\r
317 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
318 this->cbSolid->Enable(fiInfo->fSolid);
\r
319 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
320 this->tcComment->Enable(fiInfo->fComment);
\r
321 if (this->uCommand == TPI_COMMAND_ADD)
\r
327 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
328 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
330 wxFileName fn(this->cbFileName->GetValue());
\r
331 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
332 this->cbFileName->SetValue(fn.GetFullName());
\r
335 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
337 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
338 this->tcPassword->Refresh();
\r
341 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
343 wxFileName fn(this->cbFileName->GetValue());
\r
344 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
345 this->cbFileName->SetValue(fn.GetFullName());
\r
348 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
350 // "Files"タブのときは処理。
\r
351 bool bReallyShow = e.GetSelection() == 3;
\r
352 if (abs(e.GetSelection()) != 3)
\r
357 // "Files"タブを表示する初回かどうか。
\r
358 if (bReallyShow && this->lcFiles->GetItemCount() == 0)
\r
361 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
363 this->lcFiles->InsertItem(i, this->files[i]);
\r
367 switch (this->uCommand)
\r
369 case TPI_COMMAND_EXTRACT:
\r
372 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
375 bool fDTVWarning = false;
\r
376 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
378 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
379 wxFileName fnStored(this->files[i]);
\r
380 if (! this->cbIgnorePath->IsChecked())
\r
382 szOutputFile += fnStored.GetPathWithSep();
\r
384 szOutputFile += fnStored.GetFullName();
\r
385 wxFileName fnOutput(szOutputFile);
\r
386 if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
388 fDTVWarning = true;
\r
391 this->lcFiles->SetItemTextColour(i, * wxRED);
\r
396 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
\r
400 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
402 this->cbIgnorePath->SetValue(true);
\r
405 this->OnTabChanged(e);
\r
410 case TPI_COMMAND_ADD:
\r
411 case TPI_COMMAND_CREATE:
\r
413 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
417 this->lcFiles->SetItem(i, 1, this->files[i]);
\r