OSDN Git Service

書庫化可能な形式かどうかを表すTPI_FORMATINFO::fArchiveを追加。
[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                 MainFrame * frm_main = (MainFrame *) this->GetParent();
119                 this->cbDir->SetValue(frm_main->fnArchive.GetPath());
120                 this->cbFileName->SetValue(frm_main->fnArchive.GetFullName());
121                 this->tcComment->SetValue(frm_main->szComment);
122
123                 // \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
124                 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)
125                 {
126                         wxNotebookEvent e;
127                         e.SetSelection(-3);
128                         this->OnTabChanged(e);
129                 }
130                 return;
131         }
132
133         // \83\89\83C\83u\83\89\83\8a\82ð\8c\9f\8dõ\81B
134         TPIHandle tpi;
135         wxFileSystem fs;
136         fs.ChangePathTo(FE_DIR_B_LIB, true);
137         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
138         while (! szTPIName.IsEmpty())
139         {
140                 // \83\8d\81[\83h\81B
141                 if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))
142                 {
143                         // \91Î\89\9e\82·\82é\8c`\8e®\96¼\82ð\8eæ\93¾\81B
144                         TPI_FORMATINFO fiInfo;
145                         if (tpi.GetFormatInformation(& fiInfo, true))
146                         {
147                                 do
148                                 {
149                                         if (fiInfo.llSupportedCommand & TPI_COMMAND_ADD && (this->files.GetCount() == 1 || fiInfo.fArchive))
150                                         {
151                                                 fiInfo.szTPIName = szTPIName;
152                                                 this->afInfo.Add(fiInfo);
153                                                 this->chType->Append(fiInfo.szTypeName);
154                                         }
155                                 }
156                                 while (tpi.GetFormatInformation(& fiInfo, false));
157                         }
158                         tpi.FreeLibrary();
159                 }
160                 szTPIName = fs.FindNext();
161         }
162
163         // \82Æ\82è\82 \82¦\82¸\8dÅ\8f\89\82Ì\8c`\8e®\82É\82µ\82Ä\82¨\82­\81B
164         this->chType->SetSelection(0);
165         wxCommandEvent e;
166         e.SetInt(0);
167         this->OnChoice(e);
168 }
169
170 void MakeDialog::OnBtnDefault(wxCommandEvent&)
171 {
172         this->cbDir->SetValue(((MainFrame *) this->GetParent())->conf.Read(wxT("DefaultPath"), wxEmptyString));
173 }
174
175 void MakeDialog::OnBtnDesktop(wxCommandEvent&)
176 {
177         wxFileName fn(wxFileName::GetHomeDir(), wxT("Desktop"));
178         this->cbDir->SetValue(fn.GetFullPath());
179 }
180
181 void MakeDialog::OnBtnCurrent(wxCommandEvent&)
182 {
183         this->cbDir->SetValue(((MainFrame *) this->GetParent())->fnArchive.GetPath());
184 }
185
186 void MakeDialog::OnBtnBrowse(wxCommandEvent&)
187 {
188         wxDirDialog dd(this);
189         dd.SetPath(this->cbDir->GetValue());
190         if (dd.ShowModal() == wxID_OK)
191         {
192                 this->cbDir->SetValue(dd.GetPath());
193         }
194 }
195
196 void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
197 {
198         wxFileDialog fd(this);
199         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
200         if (fd.ShowModal() == wxID_OK)
201         {
202                 this->tcKeyfile->SetValue(fd.GetPath());
203         }
204 }
205
206 void MakeDialog::OnBtnOK(wxCommandEvent&)
207 {
208         this->EndModal(wxID_OK);
209 }
210
211 void MakeDialog::OnBtnCancel(wxCommandEvent&)
212 {
213         this->EndModal(wxID_CANCEL);
214 }
215
216 void MakeDialog::OnChoice(wxCommandEvent& e)
217 {
218         TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];
219         // \8c`\8e®\82ª\8ae\8eí\90Ý\92è\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\81B
220         this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);
221         this->scLevel->SetValue(fiInfo->sCompressLevelMax);
222         this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);
223         this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);
224         this->scRR->SetValue(fiInfo->sRecoveryRecordMin);
225         this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);
226         this->cbSplitSize->Enable(fiInfo->fMultiVolume);
227         this->tcPassword->Enable(fiInfo->fEncryptPassword);
228         this->cbUnmask->Enable(fiInfo->fEncryptPassword);
229         this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);
230         this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);
231         this->cbMakeSFX->Enable(fiInfo->fSFX);
232         this->cbSolid->Enable(fiInfo->fSolid);
233         this->cbMMOptimize->Enable(fiInfo->fMMOptimize);
234         this->tcComment->Enable(fiInfo->fComment);
235 }
236
237 void MakeDialog::OnCbUnmask(wxCommandEvent&)
238 {
239         this->tcPassword->SetWindowStyle(this->tcPassword->GetWindowStyle() & (this->cbUnmask->IsChecked() ? ~ wxTE_PASSWORD : wxTE_PASSWORD));
240         this->tcPassword->Refresh();
241 }
242
243 void MakeDialog::OnTabChanged(wxNotebookEvent& e)
244 {
245         // "Files"\83^\83u\82Ì\82Æ\82«\82Í\8f\88\97\9d\81B
246         bool bReallyShow = e.GetSelection() == 3;
247         if (abs(e.GetSelection()) != 3)
248         {
249                 return;
250         }
251
252         // "Files"\83^\83u\82ð\95\\8e¦\82·\82é\8f\89\89ñ\82©\82Ç\82¤\82©\81B
253         if (bReallyShow && this->lcFiles->GetItemCount() == 0)
254         {
255                 // \83t\83@\83C\83\8b\83\8a\83X\83g\82ð\92Ç\89Á\81B
256                 for (size_t i = 0; i < this->files.GetCount(); i++)
257                 {
258                         this->lcFiles->InsertItem(i, this->files[i]);
259                 }
260         }
261
262         if (bIsMake)
263         {
264                 // \8ai\94[\83p\83X\82ð\90\84\91ª\81B
265                 for (size_t i = 0; i < this->files.GetCount(); i++)
266                 {
267                         if (bReallyShow)
268                         {
269                                 this->lcFiles->SetItem(i, 1, this->files[i]);
270                         }
271                 }
272         }
273         else
274         {
275                 // \83t\83@\83C\83\8b\82Ì\8fo\97Í\90æ\82ð\90\84\91ª\81B
276                 wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();
277
278                 // \8ae\83t\83@\83C\83\8b\82É\83p\83X\82ð\95t\89Á\81B
279                 bool fDTVWarning = false;
280                 for (size_t i = 0; i < this->files.GetCount(); i++)
281                 {
282                         wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();
283                         wxFileName fnStored(this->files[i]);
284                         if (! this->cbIgnorePath->IsChecked())
285                         {
286                                 szOutputFile += fnStored.GetPathWithSep();
287                         }
288                         szOutputFile += fnStored.GetFullName();
289                         wxFileName fnOutput(szOutputFile);
290                         if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))
291                         {
292                                 fDTVWarning = true;
293                                 if (bReallyShow)
294                                 {
295                                         this->lcFiles->SetItemTextColour(i, * wxRED);
296                                 }
297                         }
298                         if (bReallyShow)
299                         {
300                                 this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());
301                         }
302                 }
303
304                 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)
305                 {
306                         this->cbIgnorePath->SetValue(true);
307                         if (bReallyShow)
308                         {
309                                 this->OnTabChanged(e);
310                         }
311                 }
312         }
313 }