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
198 wxDir fs(L_DIR_B_LIB);
\r
199 wxString szTPIName;
\r
200 if (fs.GetFirst(& szTPIName,wxT("*" TPI_EXT)))
\r
205 wxString szLibName = L_DIR_B_LIB + szTPIName;
\r
206 if (tpi.InitLibrary(szLibName, wxEmptyString, 0))
\r
209 TPI_FORMATINFO fiInfo;
\r
210 if (tpi.GetFormatInformation(& fiInfo, true))
\r
214 if (fiInfo.eSupportedCommand & TPI_COMMAND_CREATE && (this->files.GetCount() == 1 || fiInfo.fArchive))
\r
216 fiInfo.szTPIName = szLibName;
\r
217 this->afInfo.Add(fiInfo);
\r
218 this->chType->Append(fiInfo.szTypeName);
\r
221 while (tpi.GetFormatInformation(& fiInfo, false));
\r
226 while (fs.GetNext(& szTPIName));
\r
229 if (this->chType->GetCount() == 0)
\r
232 XRCCTRL(* this, "btnOK", wxButton)->Disable();
\r
236 // とりあえず最初の形式にしておく。
\r
237 this->chType->SetSelection(0);
\r
245 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
247 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
250 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
252 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
253 this->cbDir->SetValue(fn.GetFullPath());
\r
256 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
258 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
261 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
263 wxDirDialog dd(this);
\r
264 dd.SetPath(this->cbDir->GetValue());
\r
265 if (dd.ShowModal() == wxID_OK)
\r
267 this->cbDir->SetValue(dd.GetPath());
\r
271 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
273 wxFileDialog fd(this);
\r
274 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
275 if (fd.ShowModal() == wxID_OK)
\r
277 this->tcKeyfile->SetValue(fd.GetPath());
\r
281 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
284 if (this->uCommand != TPI_COMMAND_ADD)
\r
286 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
287 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
288 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
289 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
290 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
292 this->EndModal(wxID_OK);
\r
295 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
297 this->EndModal(wxID_CANCEL);
\r
300 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
302 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
303 // 形式が各種設定に対応しているか。
\r
305 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
306 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
307 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
308 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
314 this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);
\r
315 this->scLevel->SetValue(fiInfo->nCompressLevelMax);
\r
316 this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);
\r
317 this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);
\r
318 this->scRR->SetValue(fiInfo->nRecoveryRecordMin);
\r
319 this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);
\r
320 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
321 this->cbSolid->Enable(fiInfo->fSolid);
\r
322 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
323 this->tcComment->Enable(fiInfo->fComment);
\r
324 if (this->uCommand == TPI_COMMAND_ADD)
\r
330 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
331 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
333 wxFileName fn(this->cbFileName->GetValue());
\r
334 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
335 this->cbFileName->SetValue(fn.GetFullName());
\r
338 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
340 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
341 this->tcPassword->Refresh();
\r
344 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
346 wxFileName fn(this->cbFileName->GetValue());
\r
347 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
348 this->cbFileName->SetValue(fn.GetFullName());
\r
351 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
353 // "Files"タブのときは処理。
\r
354 bool bReallyShow = e.GetSelection() == 3;
\r
355 if (abs(e.GetSelection()) != 3)
\r
360 // "Files"タブを表示する初回かどうか。
\r
361 if (bReallyShow && this->lcFiles->GetItemCount() == 0)
\r
364 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
366 this->lcFiles->InsertItem(i, this->files[i]);
\r
370 switch (this->uCommand)
\r
372 case TPI_COMMAND_EXTRACT:
\r
375 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
378 bool fDTVWarning = false;
\r
379 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
381 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
382 wxFileName fnStored(this->files[i]);
\r
383 if (! this->cbIgnorePath->IsChecked())
\r
385 szOutputFile += fnStored.GetPathWithSep();
\r
387 szOutputFile += fnStored.GetFullName();
\r
388 wxFileName fnOutput(szOutputFile);
\r
389 if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
391 fDTVWarning = true;
\r
394 this->lcFiles->SetItemTextColour(i, * wxRED);
\r
399 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
\r
403 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
405 this->cbIgnorePath->SetValue(true);
\r
408 this->OnTabChanged(e);
\r
413 case TPI_COMMAND_ADD:
\r
414 case TPI_COMMAND_CREATE:
\r
416 for (size_t i = 0; i < this->files.GetCount(); i++)
\r
420 this->lcFiles->SetItem(i, 1, this->files[i]);
\r