OSDN Git Service

$Idを反映するよう変更。
[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$
20 *******************************************************************************/
21
22 #include "lychee.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.GetCount() < 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))
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));
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         this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.Read(wxT("DefaultPath"), wxEmptyString));
171 }
172
173 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
174 {
175         wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
176         this->cbDir->SetValue(fn.GetFullPath());
177 }
178
179 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
180 {
181         this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
182 }
183
184 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
185 {
186         wxDirDialog dd(this);
187         dd.SetPath(this->cbDir->GetValue());
188         if (dd.ShowModal() == wxID_OK)
189         {
190                 this->cbDir->SetValue(dd.GetPath());
191         }
192 }
193
194 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
195 {
196         wxFileDialog fd(this);
197         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
198         if (fd.ShowModal() == wxID_OK)
199         {
200                 this->tcKeyfile->SetValue(fd.GetPath());
201         }
202 }
203
204 void MakeDialog::OnBtnOK(wxCommandEvent&)
205 {
206         this->EndModal(wxID_OK);
207 }
208
209 void MakeDialog::OnBtnCancel(wxCommandEvent&)
210 {
211         this->EndModal(wxID_CANCEL);
212 }
213
214 void MakeDialog::OnChoice(wxCommandEvent& e)
215 {
216         TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
217         // \8c`\8e®\82ª\8ae\8eí\90Ý\92è\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\81B
218         this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
219         this->scLevel->SetValue(fiInfo->sCompressLevelMax);
220         this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
221         this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
222         this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
223         this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
224         this->cbSplitSize->Enable(fiInfo->fMultiVolume);
225         this->tcPassword->Enable(fiInfo->fEncryptPassword);
226         this->cbUnmask->Enable(fiInfo->fEncryptPassword);
227         this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
228         this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
229         this->cbMakeSFX->Enable(fiInfo->fSFX);
230         this->cbSolid->Enable(fiInfo->fSolid);
231         this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
232         this->tcComment->Enable(fiInfo->fComment);
233 }
234
235 void MakeDialog::OnCbUnmask(wxCommandEvent&)
236 {
237         this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
238         this->tcPassword->Refresh();
239 }
240
241 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
242 {
243         // "Files"\83^\83u\82Ì\82Æ\82«\82Í\8f\88\97\9d\81B
244         bool bReallyShow = e.GetSelection() == 3;
245         if (abs(e.GetSelection()) != 3)
246         {
247                 return;
248         }
249
250         // "Files"\83^\83u\82ð\95\\8e¦\82·\82é\8f\89\89ñ\82©\82Ç\82¤\82©\81B
251         if (bReallyShow && this->lcFiles->GetItemCount() == 0)
252         {
253                 // \83t\83@\83C\83\8b\83\8a\83X\83g\82ð\92Ç\89Á\81B
254                 for (size_t i = 0; i < this->files.GetCount(); i++)
255                 {
256                         this->lcFiles->InsertItem(i, this->files[i]);
257                 }
258         }
259
260         if (bIsMake)
261         {
262                 // \8ai\94[\83p\83X\82ð\90\84\91ª\81B
263                 for (size_t i = 0; i < this->files.GetCount(); i++)
264                 {
265                         if (bReallyShow)
266                         {
267                                 this->lcFiles->SetItem(i, 1, this->files[i]);
268                         }
269                 }
270         }
271         else
272         {
273                 // \83t\83@\83C\83\8b\82Ì\8fo\97Í\90æ\82ð\90\84\91ª\81B
274                 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
275
276                 // \8ae\83t\83@\83C\83\8b\82É\83p\83X\82ð\95t\89Á\81B
277                 bool fDTVWarning = false;
278                 for (size_t i = 0; i < this->files.GetCount(); i++)
279                 {
280                         wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
281                         wxFileName fnStored(this->files[i]);
282                         if (! this->cbIgnorePath->IsChecked())
283                         {
284                                 szOutputFile += fnStored.GetPathWithSep();
285                         }
286                         szOutputFile += fnStored.GetFullName();
287                         wxFileName fnOutput(szOutputFile);
288                         if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
289                         {
290                                 fDTVWarning = true;
291                                 if (bReallyShow)
292                                 {
293                                         this->lcFiles->SetItemTextColour(i, * wxRED);
294                                 }
295                         }
296                         if (bReallyShow)
297                         {
298                                 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
299                         }
300                 }
301
302                 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)
303                 {
304                         this->cbIgnorePath->SetValue(true);
305                         if (bReallyShow)
306                         {
307                                 this->OnTabChanged(e);
308                         }
309                 }
310         }
311 }