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->cbSolid = XRCCTRL(* this, "cbSolid", wxCheckBox);
\r
80 this->cbMMOptimize = XRCCTRL(* this, "cbMMOptimize", wxCheckBox);
\r
81 this->cbCompressHeader = XRCCTRL(* this, "cbCompressHeader", wxCheckBox);
\r
82 this->cbMakeSFX = XRCCTRL(* this, "cbMakeSFX", wxCheckBox);
\r
84 this->tcComment = XRCCTRL(* this, "tcComment", wxTextCtrl);
\r
86 this->tcPassword = XRCCTRL(* this, "tcPassword", wxTextCtrl);
\r
87 this->tcKeyfile = XRCCTRL(* this, "tcKeyfile", wxTextCtrl);
\r
88 this->cbSplitSize = XRCCTRL(* this, "cbSplitSize", wxComboBox);
\r
89 this->cbUnmask = XRCCTRL(* this, "cbUnmask", wxCheckBox);
\r
90 this->cbEncryptHeader = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);
\r
91 this->chEncryptMethod = XRCCTRL(* this, "chEncryptMethod", wxChoice);
\r
93 this->lcFiles = XRCCTRL(* this, "lcFiles", myListCtrl2);
\r
96 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
97 this->lcFiles->SetSingleStyle(wxLC_VIRTUAL);
\r
98 this->lcFiles->InsertColumn(0, _("Input"), wxLIST_FORMAT_LEFT, 150);
\r
99 this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT, 290);
\r
100 this->lcFiles->asInput = & this->files;
\r
101 this->lcFiles->atDangerItem.SetTextColour(* wxRED);
\r
103 ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
106 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
107 wxString szArcPath = frm_main->fnArchive.GetPath();
\r
110 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)
\r
112 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_PATH, i);
\r
118 this->cbDir->Append(sz);
\r
121 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)
\r
123 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_NAME, i);
\r
129 this->cbFileName->Append(sz);
\r
133 this->cbDir->SetValue(szArcPath);
\r
136 switch (this->uCommand)
\r
138 case TPI_COMMAND_EXTRACT:
\r
140 this->SetTitle(_("Extract"));
\r
141 this->tcComment->SetValue(frm_main->aiArchive.szComment);
\r
144 this->scLevel->Disable();
\r
145 this->scRR->Disable();
\r
146 this->cbSolid->Disable();
\r
147 this->cbMMOptimize->Disable();
\r
148 this->tcComment->SetEditable(false);
\r
149 this->cbEncryptHeader->Disable();
\r
150 this->chEncryptMethod->Disable();
\r
151 case TPI_COMMAND_ADD:
\r
152 // コントロールを無効化(展開時も)。
\r
153 this->cbFileName->Disable();
\r
154 this->chType->Disable();
\r
155 this->chDirMake->Enable();
\r
156 this->cbSplitSize->Disable();
\r
157 this->cbCompressHeader->Disable();
\r
158 this->cbMakeSFX->Disable();
\r
161 this->cbFileName->SetValue(frm_main->fnArchive.GetFullName());
\r
164 this->afInfo.Add(frm_main->aiArchive.fiInfo);
\r
165 this->chType->Append(frm_main->aiArchive.fiInfo.szTypeName);
\r
166 this->chType->SetSelection(0);
\r
173 if (this->uCommand != TPI_COMMAND_ADD)
\r
177 this->SetTitle(_("Add"));
\r
179 // コントロールを無効化(追加時のみ)。
\r
180 this->cbDir->Disable();
\r
181 this->chDirMake->Disable();
\r
182 XRCCTRL(* this, "btnDefault", wxButton)->Disable();
\r
183 XRCCTRL(* this, "btnDesktop", wxButton)->Disable();
\r
184 XRCCTRL(* this, "btnCurrent", wxButton)->Disable();
\r
185 XRCCTRL(* this, "btnBrowse", wxButton)->Disable();
\r
187 case TPI_COMMAND_CREATE:
\r
188 this->SetTitle(_("Create"));
\r
190 // 書庫名を設定。初期化の都合上.を付加しておく。
\r
191 this->cbFileName->SetValue(frm_main->fnArchive.GetName() + wxT('.'));
\r
195 wxDir fs(L_DIR_B_LIB);
\r
196 wxString szTPIName;
\r
197 if (fs.GetFirst(& szTPIName,wxT("*" TPI_EXT)))
\r
202 wxString szLibName = L_DIR_B_LIB + szTPIName;
\r
203 if (tpi.InitLibrary(szLibName, wxEmptyString))
\r
206 TPI_FORMATINFO fiInfo;
\r
207 if (tpi.GetFormatInformation(& fiInfo, true))
\r
211 if (fiInfo.eSupportedCommand & TPI_COMMAND_CREATE && (this->lcFiles->asInput->GetCount() == 1 || fiInfo.fArchive))
\r
213 fiInfo.szTPIName = szLibName;
\r
214 this->afInfo.Add(fiInfo);
\r
215 this->chType->Append(fiInfo.szTypeName);
\r
218 while (tpi.GetFormatInformation(& fiInfo));
\r
223 while (fs.GetNext(& szTPIName));
\r
226 if (this->chType->GetCount() == 0)
\r
229 XRCCTRL(* this, "btnOK", wxButton)->Disable();
\r
233 // とりあえず最初の形式にしておく。
\r
234 this->chType->SetSelection(0);
\r
241 // 展開/格納先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
242 if (this->lcFiles->asInput->GetCount() < 3000 ||
\r
244 this->uCommand == TPI_COMMAND_EXTRACT ?
\r
245 _("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?") :
\r
246 _("The files you want to store are too many, so it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure the path of the files are no problem, you can skip this scanning process. Do you want to scan for DTV problem?"),
\r
252 this->OnTabChanged(e);
\r
258 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
260 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
263 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
265 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
266 this->cbDir->SetValue(fn.GetFullPath());
\r
269 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
271 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
274 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
276 wxDirDialog dd(this);
\r
277 dd.SetPath(this->cbDir->GetValue());
\r
278 if (dd.ShowModal() == wxID_OK)
\r
280 this->cbDir->SetValue(dd.GetPath());
\r
284 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
286 wxFileDialog fd(this);
\r
287 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
288 if (fd.ShowModal() == wxID_OK)
\r
290 this->tcKeyfile->SetValue(fd.GetPath());
\r
294 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
297 if (this->uCommand != TPI_COMMAND_ADD)
\r
299 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
300 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
301 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
302 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
303 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
305 this->EndModal(wxID_OK);
\r
308 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
310 this->EndModal(wxID_CANCEL);
\r
313 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
315 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
316 // 形式が各種設定に対応しているか。
\r
318 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
319 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
320 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
321 this->chEncryptMethod->Enable(fiInfo->fEncryptPassword || fiInfo->fEncryptKeyFile);
\r
322 XRCCTRL(* this, "btnBrowseKF", wxButton)->Enable(fiInfo->fEncryptKeyFile);
\r
323 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
329 this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);
\r
330 this->scLevel->SetValue(fiInfo->nCompressLevelMax);
\r
331 this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);
\r
332 this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);
\r
333 this->scRR->SetValue(fiInfo->nRecoveryRecordMin);
\r
334 this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);
\r
335 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
336 this->cbCompressHeader->Enable(fiInfo->fCompressHeader);
\r
337 this->cbSolid->Enable(fiInfo->fSolid);
\r
338 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
339 this->tcComment->Enable(fiInfo->fComment);
\r
340 if (this->uCommand == TPI_COMMAND_ADD)
\r
346 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
347 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
349 wxFileName fn(this->cbFileName->GetValue());
\r
350 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
351 this->cbFileName->SetValue(fn.GetFullName());
\r
354 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
356 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
357 this->tcPassword->Refresh();
\r
360 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
362 wxFileName fn(this->cbFileName->GetValue());
\r
363 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
364 this->cbFileName->SetValue(fn.GetFullName());
\r
367 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
369 // "Files"タブのときは処理。
\r
370 if (e.GetSelection() != 4)
\r
374 this->lcFiles->DeleteAllItems();
\r
375 this->lcFiles->asOutput.Clear();
\r
376 this->lcFiles->apItem.Clear();
\r
378 bool fDTVWarning = false;
\r
379 switch (this->uCommand)
\r
381 case TPI_COMMAND_EXTRACT:
\r
384 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
387 for (size_t i = 0; i < this->lcFiles->asInput->GetCount(); i++)
\r
389 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
390 wxFileName fnStored(this->lcFiles->asInput->Item(i));
\r
391 if (! this->cbIgnorePath->IsChecked())
\r
393 szOutputFile += fnStored.GetPathWithSep();
\r
395 wxFileName fnOutput(szOutputFile + fnStored.GetFullName());
\r
396 if (! fnOutput.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG) || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
398 fDTVWarning = true;
\r
399 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
403 this->lcFiles->apItem.Add(NULL);
\r
405 this->lcFiles->asOutput.Add(fnOutput.GetFullPath());
\r
409 case TPI_COMMAND_ADD:
\r
410 case TPI_COMMAND_CREATE:
\r
412 for (size_t i = 0; i < this->lcFiles->asInput->GetCount(); i++)
\r
414 wxFileName fnStored(this->lcFiles->asInput->Item(i));
\r
415 this->lcFiles->asOutput.Add(this->cbIgnorePath->IsChecked() ? fnStored.GetFullName() : fnStored.GetFullPath());
\r
416 fnStored = wxFileName(this->lcFiles->asOutput.Item(i));
\r
417 if (fnStored.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
419 fDTVWarning = true;
\r
420 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
424 this->lcFiles->apItem.Add(NULL);
\r
435 _("This archive may have Directory Traversal Vulnerability(DTV) problem, %s It is strongly recommended to ignore file path. Would you like to do so?"),
\r
436 (this->uCommand == TPI_COMMAND_EXTRACT ?
\r
437 _("and some danger files may be extracted to the unexpected system directory!") :
\r
438 _("and some danger files may be stored!")
\r
441 if (::AskDlg(sz, this) == wxYES)
\r
443 this->cbIgnorePath->SetValue(true);
\r
444 this->OnTabChanged(e);
\r
449 this->lcFiles->SetItemCount(this->lcFiles->asInput->GetCount());
\r
452 //******************************************************************************
\r
454 //******************************************************************************
\r
456 IMPLEMENT_DYNAMIC_CLASS(myListCtrl2, wxListView)
\r
458 //******************************************************************************
\r
460 //******************************************************************************
\r
461 wxString myListCtrl2::OnGetItemText(long i, long column) const
\r
467 return this->asInput->Item(i);
\r
469 return this->asOutput[i];
\r
471 return wxEmptyString;
\r
475 wxListItemAttr * myListCtrl2::OnGetItemAttr(long i) const
\r
477 return (wxListItemAttr *) this->apItem[i];
\r