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 // とりあえず最初の形式にしておく。
\r
227 this->chType->SetSelection(0);
\r
237 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
239 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
242 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
244 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
245 this->cbDir->SetValue(fn.GetFullPath());
\r
248 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
250 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
253 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
255 wxDirDialog dd(this);
\r
256 dd.SetPath(this->cbDir->GetValue());
\r
257 if (dd.ShowModal() == wxID_OK)
\r
259 this->cbDir->SetValue(dd.GetPath());
\r
263 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
265 wxFileDialog fd(this);
\r
266 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
267 if (fd.ShowModal() == wxID_OK)
\r
269 this->tcKeyfile->SetValue(fd.GetPath());
\r
273 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
276 if (this->uCommand != TPI_COMMAND_ADD)
\r
278 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
279 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
280 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
281 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
282 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
284 this->EndModal(wxID_OK);
\r
287 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
289 this->EndModal(wxID_CANCEL);
\r
292 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
294 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
295 // 形式が各種設定に対応しているか。
\r
297 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
298 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
299 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
300 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
306 this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
\r
307 this->scLevel->SetValue(fiInfo->sCompressLevelMax);
\r
308 this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
\r
309 this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
\r
310 this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
\r
311 this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
\r
312 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
313 this->cbSolid->Enable(fiInfo->fSolid);
\r
314 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
315 this->tcComment->Enable(fiInfo->fComment);
\r
316 if (this->uCommand == TPI_COMMAND_ADD)
\r
322 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
323 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
325 wxFileName fn(this->cbFileName->GetValue());
\r
326 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
327 this->cbFileName->SetValue(fn.GetFullName());
\r
330 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
332 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
333 this->tcPassword->Refresh();
\r
336 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
338 wxFileName fn(this->cbFileName->GetValue());
\r
339 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
340 this->cbFileName->SetValue(fn.GetFullName());
\r
343 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
345 // "Files"タブのときは処理。
\r
346 bool bReallyShow = e.GetSelection() == 3;
\r
347 if (abs(e.GetSelection()) != 3)
\r
352 // "Files"タブを表示する初回かどうか。
\r
353 if (bReallyShow && this->lcFiles->GetItemCount() == 0)
\r
356 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
358 this->lcFiles->InsertItem(i, this->files[i]);
\r
362 switch (this->uCommand)
\r
364 case TPI_COMMAND_EXTRACT:
\r
367 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
370 bool fDTVWarning = false;
\r
371 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
373 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
374 wxFileName fnStored(this->files[i]);
\r
375 if (! this->cbIgnorePath->IsChecked())
\r
377 szOutputFile += fnStored.GetPathWithSep();
\r
379 szOutputFile += fnStored.GetFullName();
\r
380 wxFileName fnOutput(szOutputFile);
\r
381 if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
383 fDTVWarning = true;
\r
386 this->lcFiles->SetItemTextColour(i, * wxRED);
\r
391 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
\r
395 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
397 this->cbIgnorePath->SetValue(true);
\r
400 this->OnTabChanged(e);
\r
405 case TPI_COMMAND_ADD:
\r
406 case TPI_COMMAND_CREATE:
\r
408 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
412 this->lcFiles->SetItem(i, 1, this->files[i]);
\r