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 if (! this->cbDir->GetValue().IsEmpty())
\r
102 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
103 this->lcFiles->SetSingleStyle(wxLC_VIRTUAL);
\r
104 this->lcFiles->InsertColumn(0, _("Input"), wxLIST_FORMAT_LEFT, 150);
\r
105 this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT, 290);
\r
106 this->lcFiles->asInput = this->files;
\r
107 this->lcFiles->atDangerItem.SetTextColour(* wxRED);
\r
109 ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));
\r
112 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
113 wxString szArcPath = frm_main->fnArchive.GetPath(), szArcName = frm_main->fnArchive.GetName();
\r
116 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)
\r
118 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_PATH, i);
\r
124 this->cbDir->Append(sz);
\r
127 for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)
\r
129 wxString sz = frm_main->conf.ReadHistory(CONF_HISTORY_NAME, i);
\r
135 this->cbFileName->Append(sz);
\r
139 this->cbDir->SetValue(szArcPath);
\r
142 switch (this->uCommand)
\r
144 case TPI_COMMAND_EXTRACT:
\r
146 this->SetTitle(_("Extract"));
\r
147 this->tcComment->SetValue(frm_main->aiArchive.szComment);
\r
150 this->scLevel->Disable();
\r
151 this->scRR->Disable();
\r
152 this->cbSolid->Disable();
\r
153 this->cbMMOptimize->Disable();
\r
154 this->tcComment->SetEditable(false);
\r
155 this->cbEncryptHeader->Disable();
\r
156 this->chEncryptMethod->Disable();
\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->cbCompressHeader->Disable();
\r
164 this->cbMakeSFX->Disable();
\r
167 this->cbFileName->SetValue(szArcName);
\r
170 this->afInfo.Add(frm_main->aiArchive.fiInfo);
\r
171 this->chType->Append(frm_main->aiArchive.fiInfo.szTypeName);
\r
172 this->chType->SetSelection(0);
\r
179 if (this->uCommand != TPI_COMMAND_ADD)
\r
183 this->SetTitle(_("Add"));
\r
185 // コントロールを無効化(追加時のみ)。
\r
186 this->cbDir->Disable();
\r
187 this->chDirMake->Disable();
\r
188 XRCCTRL(* this, "btnDefault", wxButton)->Disable();
\r
189 XRCCTRL(* this, "btnDesktop", wxButton)->Disable();
\r
190 XRCCTRL(* this, "btnCurrent", wxButton)->Disable();
\r
191 XRCCTRL(* this, "btnBrowse", wxButton)->Disable();
\r
193 case TPI_COMMAND_CREATE:
\r
194 this->SetTitle(_("Create"));
\r
196 // 書庫名を設定。初期化の都合上.を付加しておく。
\r
197 this->cbFileName->SetValue(szArcName + wxT('.'));
\r
201 wxDir fs(L_DIR_B_LIB);
\r
202 wxString szTPIName;
\r
203 if (fs.GetFirst(& szTPIName,wxT("*" TPI_EXT)))
\r
208 wxString szLibName = L_DIR_B_LIB + szTPIName;
\r
209 if (tpi.InitLibrary(szLibName, wxEmptyString, 0))
\r
212 TPI_FORMATINFO fiInfo;
\r
213 if (tpi.GetFormatInformation(& fiInfo, true))
\r
217 if (fiInfo.eSupportedCommand & TPI_COMMAND_CREATE && (this->lcFiles->asInput.GetCount() == 1 || fiInfo.fArchive))
\r
219 fiInfo.szTPIName = szLibName;
\r
220 this->afInfo.Add(fiInfo);
\r
221 this->chType->Append(fiInfo.szTypeName);
\r
224 while (tpi.GetFormatInformation(& fiInfo, false));
\r
229 while (fs.GetNext(& szTPIName));
\r
232 if (this->chType->GetCount() == 0)
\r
235 XRCCTRL(* this, "btnOK", wxButton)->Disable();
\r
239 // とりあえず最初の形式にしておく。
\r
240 this->chType->SetSelection(0);
\r
247 // 展開/格納先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。
\r
248 if (this->lcFiles->asInput.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
252 this->OnTabChanged(e);
\r
256 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
258 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
261 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
263 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
264 this->cbDir->SetValue(fn.GetFullPath());
\r
267 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
269 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
272 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
274 wxDirDialog dd(this);
\r
275 dd.SetPath(this->cbDir->GetValue());
\r
276 if (dd.ShowModal() == wxID_OK)
\r
278 this->cbDir->SetValue(dd.GetPath());
\r
282 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
284 wxFileDialog fd(this);
\r
285 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
286 if (fd.ShowModal() == wxID_OK)
\r
288 this->tcKeyfile->SetValue(fd.GetPath());
\r
292 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
295 if (this->uCommand != TPI_COMMAND_ADD)
\r
297 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
298 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
299 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
300 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
301 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
303 this->EndModal(wxID_OK);
\r
306 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
308 this->EndModal(wxID_CANCEL);
\r
311 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
313 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
314 // 形式が各種設定に対応しているか。
\r
316 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
317 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
318 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
319 this->chEncryptMethod->Enable(fiInfo->fEncryptPassword || fiInfo->fEncryptKeyFile);
\r
320 XRCCTRL(* this, "btnBrowseKF", wxButton)->Enable(fiInfo->fEncryptKeyFile);
\r
321 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
327 this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);
\r
328 this->scLevel->SetValue(fiInfo->nCompressLevelMax);
\r
329 this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);
\r
330 this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);
\r
331 this->scRR->SetValue(fiInfo->nRecoveryRecordMin);
\r
332 this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);
\r
333 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
334 this->cbCompressHeader->Enable(fiInfo->fCompressHeader);
\r
335 this->cbSolid->Enable(fiInfo->fSolid);
\r
336 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
337 this->tcComment->Enable(fiInfo->fComment);
\r
338 if (this->uCommand == TPI_COMMAND_ADD)
\r
344 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
345 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
347 wxFileName fn(this->cbFileName->GetValue());
\r
348 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
349 this->cbFileName->SetValue(fn.GetFullName());
\r
352 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
354 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
355 this->tcPassword->Refresh();
\r
358 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
360 wxFileName fn(this->cbFileName->GetValue());
\r
361 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
362 this->cbFileName->SetValue(fn.GetFullName());
\r
365 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
367 // "Files"タブのときは処理。
\r
368 if (e.GetSelection() != 3)
\r
372 this->lcFiles->DeleteAllItems();
\r
373 this->lcFiles->asOutput.Clear();
\r
374 this->lcFiles->apItem.Clear();
\r
376 switch (this->uCommand)
\r
378 case TPI_COMMAND_EXTRACT:
\r
381 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
\r
384 bool fDTVWarning = false;
\r
385 for (size_t i = 0; i < this->lcFiles->asInput.GetCount(); i++)
\r
387 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
388 wxFileName fnStored(this->lcFiles->asInput[i]);
\r
389 if (! this->cbIgnorePath->IsChecked())
\r
391 szOutputFile += fnStored.GetPathWithSep();
\r
393 wxFileName fnOutput(szOutputFile + fnStored.GetFullName());
\r
394 if (! fnOutput.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG) || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
396 fDTVWarning = true;
\r
397 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
401 this->lcFiles->apItem.Add(NULL);
\r
403 this->lcFiles->asOutput.Add(fnOutput.GetFullPath());
\r
406 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
408 this->cbIgnorePath->SetValue(true);
\r
409 this->OnTabChanged(e);
\r
413 case TPI_COMMAND_ADD:
\r
414 case TPI_COMMAND_CREATE:
\r
416 this->lcFiles->asOutput = this->lcFiles->asInput;
\r
417 this->lcFiles->apItem.SetCount(this->lcFiles->asInput.GetCount(), NULL);
\r
422 this->lcFiles->SetItemCount(this->lcFiles->asInput.GetCount());
\r
425 //******************************************************************************
\r
427 //******************************************************************************
\r
429 IMPLEMENT_DYNAMIC_CLASS(myListCtrl2, wxListView)
\r
431 //******************************************************************************
\r
433 //******************************************************************************
\r
434 wxString myListCtrl2::OnGetItemText(long i, long column) const
\r
440 return this->asInput[i];
\r
442 return this->asOutput[i];
\r
444 return wxEmptyString;
\r
448 wxListItemAttr * myListCtrl2::OnGetItemAttr(long i) const
\r
450 return (wxListItemAttr *) this->apItem[i];
\r