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
102 this->lcFiles->atExistItem.SetTextColour(* wxBLUE);
\r
104 ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
107 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
108 wxString szArcPath = frm_main->fnArchive.GetPath();
\r
111 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)
\r
113 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_PATH, i);
\r
119 this->cbDir->Append(sz);
\r
122 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)
\r
124 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_NAME, i);
\r
130 this->cbFileName->Append(sz);
\r
134 this->cbDir->SetValue(szArcPath);
\r
137 switch (this->uCommand)
\r
139 case TPI_COMMAND_EXTRACT:
\r
141 this->SetTitle(_("Extract"));
\r
142 this->tcComment->SetValue(frm_main->aiArchive.szComment);
\r
143 this->cbDir->SetFocus();
\r
146 this->scLevel->Disable();
\r
147 this->scRR->Disable();
\r
148 this->cbSolid->Disable();
\r
149 this->cbMMOptimize->Disable();
\r
150 this->tcComment->SetEditable(false);
\r
151 this->cbEncryptHeader->Disable();
\r
152 this->chEncryptMethod->Disable();
\r
153 case TPI_COMMAND_ADD:
\r
154 // コントロールを無効化(展開時も)。
\r
155 this->cbFileName->Disable();
\r
156 this->chType->Disable();
\r
157 this->chDirMake->Enable();
\r
158 this->cbSplitSize->Disable();
\r
159 this->cbCompressHeader->Disable();
\r
160 this->cbMakeSFX->Disable();
\r
163 this->cbFileName->SetValue(frm_main->fnArchive.GetFullName());
\r
166 this->afInfo.Add(frm_main->aiArchive.fiInfo);
\r
167 this->chType->Append(frm_main->aiArchive.fiInfo.szTypeName);
\r
168 this->chType->SetSelection(0);
\r
175 if (this->uCommand != TPI_COMMAND_ADD)
\r
179 this->SetTitle(_("Add"));
\r
181 // コントロールを無効化(追加時のみ)。
\r
182 this->cbDir->Disable();
\r
183 this->chDirMake->Disable();
\r
184 XRCCTRL(* this, "btnDefault", wxButton)->Disable();
\r
185 XRCCTRL(* this, "btnDesktop", wxButton)->Disable();
\r
186 XRCCTRL(* this, "btnCurrent", wxButton)->Disable();
\r
187 XRCCTRL(* this, "btnBrowse", wxButton)->Disable();
\r
189 case TPI_COMMAND_CREATE:
\r
190 this->SetTitle(_("Create"));
\r
192 // 書庫名を設定。初期化の都合上.を付加しておく。
\r
193 this->cbFileName->SetValue(frm_main->fnArchive.GetName() + wxT('.'));
\r
194 this->cbFileName->SetFocus();
\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))
\r
209 TPI_FORMATINFO fiInfo;
\r
210 if (tpi.GetFormatInformation(& fiInfo, true))
\r
214 if (fiInfo.eSupportedCommand & TPI_COMMAND_CREATE && (this->lcFiles->asInput->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));
\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
244 // 展開/格納先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
245 if (this->lcFiles->asInput->GetCount() < 3000 ||
\r
247 this->uCommand == TPI_COMMAND_EXTRACT ?
\r
248 _("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
249 _("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
255 this->OnTabChanged(e);
\r
261 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
263 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
266 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
268 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
269 this->cbDir->SetValue(fn.GetFullPath());
\r
272 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
274 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
277 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
279 wxDirDialog dd(this);
\r
280 dd.SetPath(this->cbDir->GetValue());
\r
281 if (dd.ShowModal() == wxID_OK)
\r
283 this->cbDir->SetValue(dd.GetPath());
\r
287 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
289 wxFileDialog fd(this);
\r
290 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
291 if (fd.ShowModal() == wxID_OK)
\r
293 this->tcKeyfile->SetValue(fd.GetPath());
\r
297 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
300 if (this->uCommand != TPI_COMMAND_ADD)
\r
302 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
303 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
304 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
305 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
306 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
308 this->EndModal(wxID_OK);
\r
311 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
313 this->EndModal(wxID_CANCEL);
\r
316 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
318 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
319 // 形式が各種設定に対応しているか。
\r
321 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
322 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
323 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
324 this->chEncryptMethod->Enable(fiInfo->fEncryptPassword || fiInfo->fEncryptKeyFile);
\r
325 XRCCTRL(* this, "btnBrowseKF", wxButton)->Enable(fiInfo->fEncryptKeyFile);
\r
326 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
332 this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);
\r
333 this->scLevel->SetValue(fiInfo->nCompressLevelMax);
\r
334 this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);
\r
335 this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);
\r
336 this->scRR->SetValue(fiInfo->nRecoveryRecordMin);
\r
337 this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);
\r
338 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
339 this->cbCompressHeader->Enable(fiInfo->fCompressHeader);
\r
340 this->cbSolid->Enable(fiInfo->fSolid);
\r
341 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
342 this->tcComment->Enable(fiInfo->fComment);
\r
343 if (this->uCommand == TPI_COMMAND_ADD)
\r
349 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
350 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
352 wxFileName fn(this->cbFileName->GetValue());
\r
353 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
354 this->cbFileName->SetValue(fn.GetFullName());
\r
357 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
359 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
360 this->tcPassword->Refresh();
\r
363 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
365 wxFileName fn(this->cbFileName->GetValue());
\r
366 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
367 this->cbFileName->SetValue(fn.GetFullName());
\r
370 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
372 // "Files"タブのときは処理。
\r
373 if (e.GetSelection() != 4)
\r
377 this->lcFiles->DeleteAllItems();
\r
378 this->lcFiles->asOutput.Clear();
\r
379 this->lcFiles->apItem.Clear();
\r
381 bool fDTVWarning = false;
\r
382 switch (this->uCommand)
\r
384 case TPI_COMMAND_EXTRACT:
\r
387 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
390 for (size_t i = 0; i < this->lcFiles->asInput->GetCount(); i++)
\r
392 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
393 wxFileName fnStored(this->lcFiles->asInput->Item(i));
\r
394 if (! this->cbIgnorePath->IsChecked())
\r
396 szOutputFile += fnStored.GetPathWithSep();
\r
398 wxFileName fnOutput(szOutputFile + fnStored.GetFullName());
\r
399 if (! fnOutput.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG) || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
401 fDTVWarning = true;
\r
402 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
406 this->lcFiles->apItem.Add(fnOutput.FileExists() || ::wxDirExists(fnOutput.GetFullPath()) ? & this->lcFiles->atExistItem : NULL);
\r
408 this->lcFiles->asOutput.Add(fnOutput.GetFullPath());
\r
412 case TPI_COMMAND_ADD:
\r
413 case TPI_COMMAND_CREATE:
\r
415 for (size_t i = 0; i < this->lcFiles->asInput->GetCount(); i++)
\r
417 wxFileName fnStored(this->lcFiles->asInput->Item(i));
\r
418 this->lcFiles->asOutput.Add(this->cbIgnorePath->IsChecked() ? fnStored.GetFullName() : fnStored.GetFullPath());
\r
419 fnStored = wxFileName(this->lcFiles->asOutput.Item(i));
\r
420 if (fnStored.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
422 fDTVWarning = true;
\r
423 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
427 this->lcFiles->apItem.Add(NULL);
\r
438 _("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
439 (this->uCommand == TPI_COMMAND_EXTRACT ?
\r
440 _("and some danger files may be extracted to the unexpected system directory!") :
\r
441 _("and some danger files may be stored!")
\r
444 if (::AskDlg(sz, this) == wxYES)
\r
446 this->cbIgnorePath->SetValue(true);
\r
447 this->OnTabChanged(e);
\r
452 this->lcFiles->SetItemCount(this->lcFiles->asInput->GetCount());
\r
455 //******************************************************************************
\r
457 //******************************************************************************
\r
459 IMPLEMENT_DYNAMIC_CLASS(myListCtrl2, wxListView)
\r
461 //******************************************************************************
\r
463 //******************************************************************************
\r
464 wxString myListCtrl2::OnGetItemText(long i, long column) const
\r
470 return this->asInput->Item(i);
\r
472 return this->asOutput[i];
\r
474 return wxEmptyString;
\r
478 wxListItemAttr * myListCtrl2::OnGetItemAttr(long i) const
\r
480 return (wxListItemAttr *) this->apItem[i];
\r