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_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
108 // 展開時は各種コントロールの状態を変更する。
\r
109 if (! this->bIsMake)
\r
111 this->cbFileName->Disable();
\r
112 this->chType->Disable();
\r
113 this->chDirMake->Enable();
\r
114 this->scLevel->Disable();
\r
115 this->scRR->Disable();
\r
116 this->cbSplitSize->Disable();
\r
117 this->cbEncryptHeader->Disable();
\r
118 this->cbSolid->Disable();
\r
119 this->cbMMOptimize->Disable();
\r
120 this->cbMakeSFX->Disable();
\r
121 this->tcComment->SetEditable(false);
\r
124 this->tcComment->SetValue(frm_main->szComment);
\r
126 // 展開先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
127 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
130 e.SetSelection(-3);
\r
131 this->OnTabChanged(e);
\r
136 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)
\r
138 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_PATH, i);
\r
144 this->cbDir->Append(sz);
\r
148 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)
\r
150 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_NAME, i);
\r
156 this->cbFileName->Append(sz);
\r
160 this->cbDir->SetValue(szArcPath);
\r
162 if (! this->bIsMake)
\r
165 this->cbFileName->SetValue(szArcName);
\r
171 // 書庫名を設定。初期化の都合上.を付加しておく。
\r
172 this->cbFileName->SetValue(szArcName + wxT('.'));
\r
177 fs.ChangePathTo(L_DIR_B_LIB, true);
\r
178 wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
\r
179 while (! szTPIName.IsEmpty())
\r
182 if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))
\r
185 TPI_FORMATINFO fiInfo;
\r
186 if (tpi.GetFormatInformation(& fiInfo, true))
\r
190 if (fiInfo.llSupportedCommand & TPI_COMMAND_CREATE && (this->files.GetCount() == 1 || fiInfo.fArchive))
\r
192 fiInfo.szTPIName = szTPIName;
\r
193 this->afInfo.Add(fiInfo);
\r
194 this->chType->Append(fiInfo.szTypeName);
\r
197 while (tpi.GetFormatInformation(& fiInfo, false));
\r
201 szTPIName = fs.FindNext();
\r
204 // とりあえず最初の形式にしておく。
\r
205 this->chType->SetSelection(0);
\r
211 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
213 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
216 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
218 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
219 this->cbDir->SetValue(fn.GetFullPath());
\r
222 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
224 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
227 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
229 wxDirDialog dd(this);
\r
230 dd.SetPath(this->cbDir->GetValue());
\r
231 if (dd.ShowModal() == wxID_OK)
\r
233 this->cbDir->SetValue(dd.GetPath());
\r
237 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
239 wxFileDialog fd(this);
\r
240 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
241 if (fd.ShowModal() == wxID_OK)
\r
243 this->tcKeyfile->SetValue(fd.GetPath());
\r
247 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
250 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
251 wxFileName fnCurrent(this->cbDir->GetValue(), this->bIsMake ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
252 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
253 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
254 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
256 this->EndModal(wxID_OK);
\r
259 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
261 this->EndModal(wxID_CANCEL);
\r
264 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
266 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
267 // 形式が各種設定に対応しているか。
\r
268 this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
\r
269 this->scLevel->SetValue(fiInfo->sCompressLevelMax);
\r
270 this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
\r
271 this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
\r
272 this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
\r
273 this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
\r
274 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
275 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
276 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
277 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
278 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
279 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
280 this->cbSolid->Enable(fiInfo->fSolid);
\r
281 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
282 this->tcComment->Enable(fiInfo->fComment);
\r
284 wxFileName fn(this->cbFileName->GetValue());
\r
285 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
286 this->cbFileName->SetValue(fn.GetFullName());
\r
289 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
291 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
292 this->tcPassword->Refresh();
\r
295 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
297 wxFileName fn(this->cbFileName->GetValue());
\r
298 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
299 this->cbFileName->SetValue(fn.GetFullName());
\r
302 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
304 // "Files"タブのときは処理。
\r
305 bool bReallyShow = e.GetSelection() == 3;
\r
306 if (abs(e.GetSelection()) != 3)
\r
311 // "Files"タブを表示する初回かどうか。
\r
312 if (bReallyShow && this->lcFiles->GetItemCount() == 0)
\r
315 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
317 this->lcFiles->InsertItem(i, this->files[i]);
\r
324 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
328 this->lcFiles->SetItem(i, 1, this->files[i]);
\r
335 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
338 bool fDTVWarning = false;
\r
339 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
341 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
342 wxFileName fnStored(this->files[i]);
\r
343 if (! this->cbIgnorePath->IsChecked())
\r
345 szOutputFile += fnStored.GetPathWithSep();
\r
347 szOutputFile += fnStored.GetFullName();
\r
348 wxFileName fnOutput(szOutputFile);
\r
349 if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
351 fDTVWarning = true;
\r
354 this->lcFiles->SetItemTextColour(i, * wxRED);
\r
359 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
\r
363 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
365 this->cbIgnorePath->SetValue(true);
\r
368 this->OnTabChanged(e);
\r