OSDN Git Service

Lycheeにリネーム。
[tpi/lychee.git] / src / lychee / dlg_make.cpp
1 /*******************************************************************************
2   TPI - flexible but useless plug-in framework.
3   Copyright (C) 2002-2009 Silky
4
5   This library is free software; you can redistribute it and/or modify it under
6   the terms of the GNU Lesser General Public License as published by the Free
7   Software Foundation; either version 2.1 of the License, or (at your option)
8   any later version.
9
10   This library is distributed in the hope that it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13   for more details.
14
15   You should have received a copy of the GNU Lesser General Public License along
16   with this library; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
19   $Id: dlg_make.cpp,v 1.15 2009/08/30 08:07:17 sirakaba Exp $
20 *******************************************************************************/
21
22 #include "frontend.h"
23
24 #include "dlg_make.h"
25 #include "frm_main.h"
26 #include "functions.h"
27
28 #include <wx/dirdlg.h>
29 #include <wx/arrimpl.cpp>
30
31 WX_DEFINE_OBJARRAY(ArrayTPI_FORMATINFO);
32
33 //******************************************************************************
34 // MakeDialog
35 //******************************************************************************
36
37 MakeDialog::MakeDialog(): wxDialog()
38 {
39         this->bIsMake = true;
40 }
41
42 //******************************************************************************
43 // Event Table.
44 //******************************************************************************
45
46 BEGIN_EVENT_TABLE(MakeDialog, wxDialog)
47         EVT_INIT_DIALOG(                 MakeDialog::OnInit)
48         EVT_BUTTON(XRCID("btnDefault"),  MakeDialog::OnBtnDefault)
49         EVT_BUTTON(XRCID("btnDesktop"),  MakeDialog::OnBtnDesktop)
50         EVT_BUTTON(XRCID("btnCurrent"),  MakeDialog::OnBtnCurrent)
51         EVT_BUTTON(XRCID("btnBrowse"),   MakeDialog::OnBtnBrowse)
52         EVT_BUTTON(XRCID("btnBrowseKF"), MakeDialog::OnBtnBrowseKF)
53         EVT_BUTTON(XRCID("btnOK"),       MakeDialog::OnBtnOK)
54         EVT_BUTTON(XRCID("btnCancel"),   MakeDialog::OnBtnCancel)
55         EVT_CHOICE(XRCID("chType"),      MakeDialog::OnChoice)
56         EVT_CHECKBOX(XRCID("cbUnmask"),  MakeDialog::OnCbUnmask)
57         EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbTabs"), MakeDialog::OnTabChanged)
58 END_EVENT_TABLE()
59
60 //******************************************************************************
61 // Event handler.
62 //******************************************************************************
63
64 void MakeDialog::OnInit(wxInitDialogEvent&)
65 {
66         // XRC\82Æ\8c\8b\82Ñ\82Â\82¯\81B
67         // "General"\83^\83u
68         this->cbDir             = XRCCTRL(* this, "cbDir",        wxComboBox);
69         this->cbFileName        = XRCCTRL(* this, "cbFileName",   wxComboBox);
70         this->cbOpenAfter       = XRCCTRL(* this, "cbOpenAfter",  wxCheckBox);
71         this->cbIgnorePath      = XRCCTRL(* this, "cbIgnorePath", wxCheckBox);
72         this->cbExitAfter       = XRCCTRL(* this, "cbExitAfter",  wxCheckBox);
73         this->chType            = XRCCTRL(* this, "chType",       wxChoice);
74         this->chDirMake         = XRCCTRL(* this, "chDirMake",    wxChoice);
75         // "Config"\83^\83u
76         this->scLevel           = XRCCTRL(* this, "scLevel",      wxSpinCtrl);
77         this->scRR              = XRCCTRL(* this, "scRR",         wxSpinCtrl);
78         this->tcPassword        = XRCCTRL(* this, "tcPassword",   wxTextCtrl);
79         this->tcKeyfile         = XRCCTRL(* this, "tcKeyfile",    wxTextCtrl);
80         this->cbSplitSize       = XRCCTRL(* this, "cbSplitSize",  wxComboBox);
81         this->cbUnmask          = XRCCTRL(* this, "cbUnmask",     wxCheckBox);
82         this->cbEncryptHeader   = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);
83         this->cbSolid           = XRCCTRL(* this, "cbSolid",      wxCheckBox);
84         this->cbMMOptimize      = XRCCTRL(* this, "cbMMOptimize", wxCheckBox);
85         this->cbMakeSFX         = XRCCTRL(* this, "cbMakeSFX",    wxCheckBox);
86         // "Comment"\83^\83u
87         this->tcComment         = XRCCTRL(* this, "tcComment",    wxTextCtrl);
88         // "Files"\83^\83u
89         this->lcFiles           = XRCCTRL(* this, "lcFiles",      wxListCtrl);
90
91         if (! this->cbDir->GetValue().IsEmpty())
92         {
93                 return;
94         }
95
96         // ListCtrl\82É\97ñ\82ð\92Ç\89Á\81B
97         this->lcFiles->InsertColumn(0, wxT("Input"),  wxLIST_FORMAT_LEFT,  150);
98         this->lcFiles->InsertColumn(1, wxT("Output"), wxLIST_FORMAT_LEFT,  300);
99
100         ::wxXmlResource::Get()->Unload(FE_DIR_S_XRC wxT("dlg_make.xrc"));
101
102         // \93W\8aJ\8e\9e\82Í\8ae\8eí\83R\83\93\83g\83\8d\81[\83\8b\82Ì\8fó\91Ô\82ð\95Ï\8dX\82·\82é\81B
103         if (! this->bIsMake)
104         {
105                 this->cbFileName->Disable();
106                 this->chType->Disable();
107                 this->chDirMake->Enable();
108                 this->scLevel->Disable();
109                 this->scRR->Disable();
110                 this->cbSplitSize->Disable();
111                 this->cbEncryptHeader->Disable();
112                 this->cbSolid->Disable();
113                 this->cbMMOptimize->Disable();
114                 this->cbMakeSFX->Disable();
115                 this->tcComment->SetEditable(false);
116
117                 // \8f\89\8aú\92l\82ð\90Ý\92è\81B
118                 this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
119                 this->cbFileName->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetFullName());
120
121                 // \93W\8aJ\90æ\82ð\97\\91ª\81B\82½\82¾\82µDTV\83X\83L\83\83\83\93\82É\8e\9e\8aÔ\82ª\82©\82©\82é\8fê\8d\87\82Í\83X\83L\83b\83v\89Â\94\\81B
122                 if (this->files.Count() < 3000 || ::AskDlg(wxT("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)
123                 {
124                         wxNotebookEvent e;
125                         e.SetSelection(-3);
126                         this->OnTabChanged(e);
127                 }
128                 return;
129         }
130
131         // \83\89\83C\83u\83\89\83\8a\82ð\8c\9f\8dõ\81B
132         TPIHandle tpi;
133         wxFileSystem fs;
134         fs.ChangePathTo(FE_DIR_B_LIB, true);
135         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
136         while (! szTPIName.IsEmpty())
137         {
138                 // \83\8d\81[\83h\81B
139                 if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))
140                 {
141                         // \91Î\89\9e\82·\82é\8c`\8e®\96¼\82ð\8eæ\93¾\81B
142                         TPI_FORMATINFO fiInfo;
143                         if (tpi.GetFormatInformation(& fiInfo, true) == TPI_ERROR_SUCCESS)
144                         {
145                                 do
146                                 {
147                                         if (fiInfo.llSupportedCommand & TPI_COMMAND_ADD)
148                                         {
149                                                 fiInfo.szTPIName = szTPIName;
150                                                 this->afInfo.Add(fiInfo);
151                                                 this->chType->Append(fiInfo.szTypeName);
152                                         }
153                                 }
154                                 while (tpi.GetFormatInformation(& fiInfo, false) == TPI_ERROR_SUCCESS);
155                         }
156                         tpi.FreeLibrary();
157                 }
158                 szTPIName = fs.FindNext();
159         }
160
161         // \82Æ\82è\82 \82¦\82¸\8dÅ\8f\89\82Ì\8c`\8e®\82É\82µ\82Ä\82¨\82­\81B
162         this->chType->SetSelection(0);
163         wxCommandEvent e;
164         e.SetInt(0);
165         this->OnChoice(e);
166 }
167
168 void MakeDialog::OnBtnDefault(wxCommandEvent&)
169 {
170 }
171
172 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
173 {
174         wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
175         this->cbDir->SetValue(fn.GetFullPath());
176 }
177
178 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
179 {
180         this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
181 }
182
183 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
184 {
185         wxDirDialog dd(this);
186         dd.SetPath(this->cbDir->GetValue());
187         if (dd.ShowModal() == wxID_OK)
188         {
189                 this->cbDir->SetValue(dd.GetPath());
190         }
191 }
192
193 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
194 {
195         wxFileDialog fd(this);
196         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
197         if (fd.ShowModal() == wxID_OK)
198         {
199                 this->tcKeyfile->SetValue(fd.GetPath());
200         }
201 }
202
203 void MakeDialog::OnBtnOK(wxCommandEvent&)
204 {
205         this->EndModal(wxID_OK);
206 }
207
208 void MakeDialog::OnBtnCancel(wxCommandEvent&)
209 {
210         this->EndModal(wxID_CANCEL);
211 }
212
213 void MakeDialog::OnChoice(wxCommandEvent& e)
214 {
215         TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
216         // \8c`\8e®\82ª\8ae\8eí\90Ý\92è\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\81B
217         this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
218         this->scLevel->SetValue(fiInfo->sCompressLevelMax);
219         this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
220         this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
221         this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
222         this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
223         this->cbSplitSize->Enable(fiInfo->fMultiVolume);
224         this->tcPassword->Enable(fiInfo->fEncryptPassword);
225         this->cbUnmask->Enable(fiInfo->fEncryptPassword);
226         this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
227         this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
228         this->cbMakeSFX->Enable(fiInfo->fSFX);
229         this->cbSolid->Enable(fiInfo->fSolid);
230         this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
231         this->tcComment->Enable(fiInfo->fComment);
232 }
233
234 void MakeDialog::OnCbUnmask(wxCommandEvent&)
235 {
236         this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
237         this->tcPassword->Refresh();
238 }
239
240 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
241 {
242         // "Files"\83^\83u\82Ì\82Æ\82«\82Í\8f\88\97\9d\81B
243         bool bReallyShow = e.GetSelection() == 3;
244         if (abs(e.GetSelection()) != 3)
245         {
246                 return;
247         }
248
249         // "Files"\83^\83u\82ð\95\\8e¦\82·\82é\8f\89\89ñ\82©\82Ç\82¤\82©\81B
250         if (bReallyShow && this->lcFiles->GetItemCount() == 0)
251         {
252                 // \83t\83@\83C\83\8b\83\8a\83X\83g\82ð\92Ç\89Á\81B
253                 for (size_t i = 0; i < this->files.Count(); i++)
254                 {
255                         this->lcFiles->InsertItem(i, this->files[i]);
256                 }
257         }
258
259         if (bIsMake)
260         {
261                 // \8ai\94[\83p\83X\82ð\90\84\91ª\81B
262                 for (size_t i = 0; i < this->files.Count(); i++)
263                 {
264                         if (bReallyShow)
265                         {
266                                 this->lcFiles->SetItem(i, 1, this->files[i]);
267                         }
268                 }
269         }
270         else
271         {
272                 // \83t\83@\83C\83\8b\82Ì\8fo\97Í\90æ\82ð\90\84\91ª\81B
273                 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
274
275                 // \8ae\83t\83@\83C\83\8b\82É\83p\83X\82ð\95t\89Á\81B
276                 bool fDTVWarning = false;
277                 for (size_t i = 0; i < this->files.Count(); i++)
278                 {
279                         wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
280                         wxFileName fnStored(this->files[i]);
281                         if (! this->cbIgnorePath->IsChecked())
282                         {
283                                 szOutputFile += fnStored.GetPathWithSep();
284                         }
285                         szOutputFile += fnStored.GetFullName();
286                         wxFileName fnOutput(szOutputFile);
287                         if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
288                         {
289                                 fDTVWarning = true;
290                                 if (bReallyShow)
291                                 {
292                                         this->lcFiles->SetItemTextColour(i, * wxRED);
293                                 }
294                         }
295                         if (bReallyShow)
296                         {
297                                 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
298                         }
299                 }
300
301                 if (fDTVWarning && ::AskDlg(wxT("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)
302                 {
303                         this->cbIgnorePath->SetValue(true);
304                         if (bReallyShow)
305                         {
306                                 this->OnTabChanged(e);
307                         }
308                 }
309         }
310 }