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, 0))
\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, false));
\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 || ::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
246 this->OnTabChanged(e);
\r
250 void MakeDialog::OnBtnDefault(wxCommandEvent&)
\r
252 this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.ReadId(CONF_DEFAULT_PATH, (wxString) wxEmptyString));
\r
255 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
\r
257 wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
\r
258 this->cbDir->SetValue(fn.GetFullPath());
\r
261 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
\r
263 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
\r
266 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
\r
268 wxDirDialog dd(this);
\r
269 dd.SetPath(this->cbDir->GetValue());
\r
270 if (dd.ShowModal() == wxID_OK)
\r
272 this->cbDir->SetValue(dd.GetPath());
\r
276 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
\r
278 wxFileDialog fd(this);
\r
279 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
280 if (fd.ShowModal() == wxID_OK)
\r
282 this->tcKeyfile->SetValue(fd.GetPath());
\r
286 void MakeDialog::OnBtnOK(wxCommandEvent&)
\r
289 if (this->uCommand != TPI_COMMAND_ADD)
\r
291 MainFrame * frm_main = (MainFrame *) this->GetParent();
\r
292 wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);
\r
293 frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());
\r
294 frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());
\r
295 frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());
\r
297 this->EndModal(wxID_OK);
\r
300 void MakeDialog::OnBtnCancel(wxCommandEvent&)
\r
302 this->EndModal(wxID_CANCEL);
\r
305 void MakeDialog::OnChoice(wxCommandEvent& e)
\r
307 TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
\r
308 // 形式が各種設定に対応しているか。
\r
310 this->tcPassword->Enable(fiInfo->fEncryptPassword);
\r
311 this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
\r
312 this->cbUnmask->Enable(fiInfo->fEncryptPassword);
\r
313 this->chEncryptMethod->Enable(fiInfo->fEncryptPassword || fiInfo->fEncryptKeyFile);
\r
314 XRCCTRL(* this, "btnBrowseKF", wxButton)->Enable(fiInfo->fEncryptKeyFile);
\r
315 if (this->uCommand == TPI_COMMAND_EXTRACT)
\r
321 this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);
\r
322 this->scLevel->SetValue(fiInfo->nCompressLevelMax);
\r
323 this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);
\r
324 this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);
\r
325 this->scRR->SetValue(fiInfo->nRecoveryRecordMin);
\r
326 this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);
\r
327 this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
\r
328 this->cbCompressHeader->Enable(fiInfo->fCompressHeader);
\r
329 this->cbSolid->Enable(fiInfo->fSolid);
\r
330 this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
\r
331 this->tcComment->Enable(fiInfo->fComment);
\r
332 if (this->uCommand == TPI_COMMAND_ADD)
\r
338 this->cbSplitSize->Enable(fiInfo->fMultiVolume);
\r
339 this->cbMakeSFX->Enable(fiInfo->fSFX);
\r
341 wxFileName fn(this->cbFileName->GetValue());
\r
342 fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));
\r
343 this->cbFileName->SetValue(fn.GetFullName());
\r
346 void MakeDialog::OnCbUnmask(wxCommandEvent&)
\r
348 this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
\r
349 this->tcPassword->Refresh();
\r
352 void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
\r
354 wxFileName fn(this->cbFileName->GetValue());
\r
355 fn.SetExt(this->cbMakeSFX->IsChecked() ? EXE_EXT : this->afInfo[this->chType->GetSelection()].szSuffix.BeforeFirst(wxT(';')));
\r
356 this->cbFileName->SetValue(fn.GetFullName());
\r
359 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
\r
361 // "Files"タブのときは処理。
\r
362 if (e.GetSelection() != 4)
\r
366 this->lcFiles->DeleteAllItems();
\r
367 this->lcFiles->asOutput.Clear();
\r
368 this->lcFiles->apItem.Clear();
\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->lcFiles->asInput->GetCount(); i++)
\r
381 wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
\r
382 wxFileName fnStored(this->lcFiles->asInput->Item(i));
\r
383 if (! this->cbIgnorePath->IsChecked())
\r
385 szOutputFile += fnStored.GetPathWithSep();
\r
387 wxFileName fnOutput(szOutputFile + fnStored.GetFullName());
\r
388 if (! fnOutput.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG) || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
\r
390 fDTVWarning = true;
\r
391 this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);
\r
395 this->lcFiles->apItem.Add(NULL);
\r
397 this->lcFiles->asOutput.Add(fnOutput.GetFullPath());
\r
400 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
402 this->cbIgnorePath->SetValue(true);
\r
403 this->OnTabChanged(e);
\r
407 case TPI_COMMAND_ADD:
\r
408 case TPI_COMMAND_CREATE:
\r
410 this->lcFiles->asOutput = * this->lcFiles->asInput;
\r
411 this->lcFiles->apItem.SetCount(this->lcFiles->asInput->GetCount(), NULL);
\r
416 this->lcFiles->SetItemCount(this->lcFiles->asInput->GetCount());
\r
419 //******************************************************************************
\r
421 //******************************************************************************
\r
423 IMPLEMENT_DYNAMIC_CLASS(myListCtrl2, wxListView)
\r
425 //******************************************************************************
\r
427 //******************************************************************************
\r
428 wxString myListCtrl2::OnGetItemText(long i, long column) const
\r
434 return this->asInput->Item(i);
\r
436 return this->asOutput[i];
\r
438 return wxEmptyString;
\r
442 wxListItemAttr * myListCtrl2::OnGetItemAttr(long i) const
\r
444 return (wxListItemAttr *) this->apItem[i];
\r